I'm trying to transfer php variables, that I have pulled out of a database, into three different javascript arrays. I use a php function to dynamically create a css dropdown menu, and then use a php loop to transfer the php variables into the javascript arrays. I then try to use a javascript function to initialize the attributes of the css menu. The same function is called from each of the links of the menu to update the menu based on the javascript arrays.
Here is the php function:
function createMenu()
{
//create the proper drop down menu, based on the total number of games played and the max number of games
$totalVods = count($this->VodID);
$menuArray = array();
for($i = 0; $i < $totalVods; ++$i)
{
if ($this->currentVodID != $i)
{
$menuArray[] = ($i+1);
}
}
if ( $totalVods < $this->MaxGames )
{
for ($i = $totalVods; $i < $this->MaxGames; ++$i)
{
$menuArray[] = ($this->currentVodID+1);
}
}
$totalGames = count($menuArray);
printf("<p>$this->Name</p>");
printf("<div id='cssmenu2'>");
printf('<ul>');
if ($menuArray)
{
printf('<li id="vod1" class="has-sub last"><span></span><img class="arrow" src="/images/Arrow.png">');
printf('<ul>');
if ($totalGames > 1)
{
for ($j = 0; $j < ($totalGames - 1); ++$j)
{
$vodNum = 'vod'. ($j+2);
printf("<li id='$vodNum' onclick=''><span></span></li>");
}
}
$vodNum = 'vod'. ($totalGames + 1);
printf("<li id='$vodNum' class='last' onclick=''><span></span></li>");
printf('</ul>');
}
else
{
printf('<li id="vod1"><span>Game 1</span>');
}
printf('</li>');
printf('</ul>');
printf('</div>');
//---------------------------------------------------
// function works fine up till here
// ------------------------------------------------
printf('<script>');
printf('alert("Right after totalGames");'); /* If I take this part out, up till the next comment, the rest works, but none of this part, even the alerts, works */
for($i = 0; $i < $totalVods; ++$i)
{
printf("vodName[$i] = 'Game ". ($i + 1) ."';");
printf("alert('vodName[$i]= '+vodName[$i]);");
$this->VodObject->selectVod($this->VodID[$i]);
$address = $this->VodObject->returnVod();
printf("vodAddress[$i] = '$address';");
$date = $this->VodObject->returnDate();
printf("vodDate[$i] = '$date';");
}
if ($totalVods < $this->MaxGames )
{
for ($i = $totalVods; $i < $this->MaxGames; ++$i)
{
printf("vodName[$i] = 'Game ". ($i + 1) ."';");
$gameNum = $i +1;
$address = "<div class='matchNoVOD'>There is no Game $gameNum<br />Series ended before this game.</div>";
printf("vodAddress[$i] = '$address';");
printf("vodDate[$i] = '';");
}
}/* End of the section that is having problems- if I take this out, the rest of the alerts work */
printf('alert("Right before window.onload");');
printf('window.onload = function() { switchVod(0); };');
printf('</script>');
}
In the javascript part of the above function, I access a php class called vodObject- that just accesses the database and returns the strings I want to place in the javascript array.
The javascript function that updates the css menu is placed in the part of the html, and looks like this:
<script>
var vodName = Array();
var vodAddress = Array();
var vodDate = Array();
function createfunc(i)
{
return i;
}
function switchVod(vodID)
{
alert("switchVod ran");
alert('vodID= ' + vodID);
var x=document.getElementById("vod1");
var y = x.getElementsByTagName("span");
y[0].innerHTML = vodName[vodID];
for (var i=0; i < vodName.length; i++)
{
if ( i != vodID)
{
var id = createfunc(i);
var gameNum = i + 2;
var gameID = "vod" + gameNum;
var x = document.getElementByID(gameID);
var y = x.getElementsByTagName("span");
y[0].innerHTML = vodName[i]
x.onclick = function() { switchVod(id); }
}
}
alert("after for loop");
alert("1");
document.getElementById('vodObj').innerHTML = vodAddress[vodID];
alert("2");
document.getElementById("vodDate").innerHTML = vodDate[vodID];
alert("finished");
}
</script>
The createfunc(i) is meant to get around the closure issues I heard about.
Any ideas about what I can try to fix my code? Thank you for your help, in advance!
In the JS code, you can just use var city = '<?=$city;?>';, for example.
If I got you right, you can make it using AJAX. The PHP file while print this:
echo json_encode($your_php_array);
Then, using JQuery $.getJSON method
$.getJSON('json.php', function(response) {
/* do your stuff here */
console.log(response); // This var has the json object
});
Let me know if it's useful.
Related
use one function array to other function without returning the array like javascript
this code l'm converted js to php in js same code working perfect but in php return error
Undefined variable: const
$const = array();
$array = array(1,2,3,4,5,6,7,8,9);
readdata();
for ($i = 0 ; $i < count($array) ; $i++) {
$const[5]=$i;
getall($array);
}
function dependent($array,$tances) {
echo $index5 = $const[5];
echo $index4 = $const[4];
$index3 = $const[3];
// $tances and $array for other purpose in this function
}
function getbid($array) {
$mid = 1.0;
dependent($array,$mid);
}
function getall($array) {
getbid($array);
}
function readdata() {
$latd=40;
$latm=11;
$lond=44;
$lonm=30;
$alt=0;
$tz=5;
$const[0]=$latd;
$const[1]=$latm;
$const[2]=$lond;
$const[3]=$lonm;
$const[4]=$tz;
}
i'm converted js library to php maximum js function use those array to declare in the previous function.so i want to use the same code in PHP as it is
this js i'm converted into php
in js all functions, arrays, and variables working perfect
var sconst= new Array();
var array= new Array(1,2);
readdata();
for (var i = 0 ; i < array.length ; i++) {
sconst[5]=i;
getall(array);
}
function dependent(array,mid) {
index5 = sconst[5];
index4 = sconst[4];
index3 = sconst[3];
alert(index5+' '+index4+' '+index3)
// $tances and $array for other purpose in this function
}
function getbid(array) {
var mid = 1.0;
dependent(array,mid);
}
function getall(array) {
getbid(array);
}
function readdata() {
var latd=40;
var latm=11;
var lond=44;
var lonm=30;
var alt=0;
var tz=5;
sconst[0]=latd;
sconst[1]=latm;
sconst[2]=lond;
sconst[3]=lonm;
sconst[4]=tz;
}
Your error is because $const doesn't exist in the scope of the dependent function. It also doesn't exist in the readdata function but you don't get an error there since you are not trying to read a value from it. You can resolve this most easily by adding global $const; to the dependent and readdata functions e.g.
function dependent($array,$tances) {
global $const;
echo $index5 = $const[5] . "\n";
echo $index4 = $const[4] . "\n";
$index3 = $const[3];
// $tances and $array for other purpose in this function
}
function readdata() {
global $const;
$latd=40;
$latm=11;
$lond=44;
$lonm=30;
$alt=0;
$tz=5;
$const[0]=$latd;
$const[1]=$latm;
$const[2]=$lond;
$const[3]=$lonm;
$const[4]=$tz;
}
Alternatively you need to modify your function calls to pass $const as a parameter (and return it as a value from readdata) i.e.
$const=array();
$array=array(1,2,3,4,5,6,7,8,9);
$const = readdata();
for ($i = 0 ; $i < count($array) ; $i++) {
$const[5]=$i;
getall($const, $array);
}
function dependent($const, $array, $tances) {
echo $index5 = $const[5] . "\n";
echo $index4 = $const[4] . "\n";
$index3 = $const[3];
// $tances and $array for other purpose in this function
}
function getbid($const, $array) {
$mid = 1.0;
dependent($const, $array, $mid);
}
function getall($const, $array) {
getbid($const, $array);
}
function readdata() {
$latd=40;
$latm=11;
$lond=44;
$lonm=30;
$alt=0;
$tz=5;
$const[0]=$latd;
$const[1]=$latm;
$const[2]=$lond;
$const[3]=$lonm;
$const[4]=$tz;
return $const;
}
I'm trying to create an array of strings in javascript by calling a function in my MVC controller and passing back an array of strings. This pretty simply just isn't working and I'm not sure what i need to do to amend this. below you can see both my javascript and controller code. Any help is greatly appreciated
javascript:
var optionString = #Html.Action("PopulateDashboardDropdown", "Embed", new { Dashboards = Model[0][0].Dashboards });
Controller:
public string[] PopulateDashboardDropdown(ODataResponseListDashboard[] dashboards)
{
string email = "";
//loop that finds the groupID assigned to the currently logged in user
foreach (Claim claim in ClaimsPrincipal.Current.Claims)
{
if (claim.Type == "emails")
{
email = claim.Value;
email = email.ToLower();
}
}
string[] orgs = GetOrgs(email);
string[] retVal = new string[orgs.Length];
bool[] admin = new bool[orgs.Length];
for (int i = 0; i < orgs.Length; i++)
{
admin[i] = isAdmin(orgs[i], email);
retVal[i] = "";
}
//loop that creates a string to emulate the innerHtml of a dropdown selector based on the names of all dashboards in the workspace
for (int i = 0; i < orgs.Length; i++)
{
for (int j = 0; j < dashboards[i].Value.Count; j++)
{
if (dashboards[i].Value.ElementAtOrDefault(j).DisplayName.Contains("Admin"))
{
if (admin[i])
{
retVal[i] += "<option>" + dashboards[i].Value.ElementAtOrDefault(j).DisplayName + "</option>";
}
}
else
{
retVal[i] += "<option>" + dashboards[i].Value.ElementAtOrDefault(j).DisplayName + "</option>";
}
}
}
return retVal;
}
Well, from isn't clear what is the error or what happens exactly but I see a couple of problems. I suggest the following in order to fix the code:
1) Change the result of your controller method to JsonResult:
public JsonResult PopulateDashboardDropdown(ODataResponseListDashboard[] dashboards)
{
...
return this.Json(retVal);
}
2) Get your data via an ajax call (note: you need to insert the proper url in http format. The Http.Action/Razor will not work in javascript):
$.getJSON(myUrl, function (data) {
var optionString = data;
...
});
I have a ajax call, and I am loading the data returned into a datatable
Here is my jquery ajax call
<script type="text/javascript">
var oTable;
$(document).ready(function() {
window.prettyPrint() && prettyPrint();
$('#load').click(function()
{
var v = $('#drp_v').val();
var cnt = $('#drp_cnt').val();
var ctg = $('#drp_ctg').val();
var api = $('#drp_api').val();
var nt = $('#drp_nt').val();
$.post("ajax.php",
{ 'version':v,'category':ctg,
'country':cnt,'network_id':nt,
'api':api,'func':'show_datatable'},
function(data)
{
var aColumns = [];
var columns = [];
for(var i = 0; i < data.length; i++)
{
if(i>0)
break;
keycolumns = Object.keys(data[i]);
for(j = 0; j < keycolumns.length; j++)
{
if($.inArray(keycolumns[j],aColumns.sTitle)<=0)
{
aColumns.push({sTitle: keycolumns[j]}) //Checks if
columns.push(keycolumns[j]) //Checks if
}
}
}
var oTable = $('#jsontable').dataTable({
"columns":aColumns,
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"aButtons": [
{
"sExtends": "csv",
"sButtonText": "CSV",
}
]
}
});
oTable.fnClearTable();
var row = []
for(var i = 0; i < data.length; i++)
{
for(var c = 0; c < columns.length; c++)
{
row.push( data[i][columns[c]] ) ;
}
oTable.fnAddData(row);
row = [];
}
},'json');
});
});
</script>
And here's my php function
function show_datatable($version,$ctg,$cnt,$nt,$api)
{
$cnt_table = "aw_countries_".$version;
$ctg_table = "aw_categories_".$version;
$off_table = "aw_offers_".$version;
$sizeof_ctg = count($ctg);
$cond_ctg = " ( ";
for($c = 0; $c < $sizeof_ctg ; $c++)
{
$cond_ctg = $cond_ctg." $ctg_table.category = '".$ctg[$c]."' ";
if($c < intval($sizeof_ctg-1))
$cond_ctg = $cond_ctg." OR ";
else if($c == intval($sizeof_ctg-1))
$cond_ctg = $cond_ctg." ) ";
}
$sizeof_cnt = count($cnt);
$cond_cnt = " ( ";
for($cn = 0; $cn < $sizeof_cnt ; $cn++)
{
$cond_cnt = $cond_cnt." $cnt_table.country = '".$cnt[$cn]."' ";
if($cn < intval($sizeof_cnt-1))
$cond_cnt = $cond_cnt." OR ";
else if($cn == intval($sizeof_cnt-1))
$cond_cnt = $cond_cnt." ) ";
}
$sizeof_nt = count($nt);
$cond_nt = " ( ";
for($n = 0; $n < $sizeof_nt ; $n++)
{
$cond_nt = $cond_nt." $off_table.network_id = '".$nt[$n]."' ";
if($n < intval($sizeof_nt-1))
$cond_nt = $cond_nt." OR ";
else if($n == intval($sizeof_nt-1))
$cond_nt = $cond_nt." ) ";
}
$sizeof_api = count($api);
$cond_api = " ( ";
for($a = 0; $a < $sizeof_api ; $a++)
{
$cond_api = $cond_api." $off_table.api_key = '".$api[$a]."' ";
if($a < intval($sizeof_api-1))
$cond_api = $cond_api." OR ";
else if($a == intval($sizeof_api-1))
$cond_api = $cond_api." ) ";
}
$output = "";
$sql = "SELECT *
FROM $off_table,$cnt_table,$ctg_table
WHERE $off_table.id = $cnt_table.id
AND $off_table.id = $ctg_table.id
AND ".$cond_api."
AND ".$cond_nt."
AND ".$cond_cnt."
AND ".$cond_ctg;
$result = mysql_query($sql);
$arr_result = array();
while($row = mysql_fetch_assoc($result))
{
$arr_result[] = $row;
}
$arr_result_enc = json_encode($arr_result);
echo $arr_result_enc;
}
Now, I want to modify this code. Say I want to work it like this:
I will call for v, and the AJAX will send me 100 rows once, then again 100 rows and then again 100 rows.
I mean splitting the AJAX call to returns chunks of all the data one after another. Say something like there will be multiple times when the AJAX will be called, and each time it will send me 100 chunks of data.
While the work will be going on, there will be a progress bar with a cancel button.
If I click the cancel button, then if 3 times the AJAX function have been called, it will show me 300 data and then the AJAX will be stopped. The database will show only 300 data.
JQ:
// counter that allows you to get a new set of rows
var step = 0;
// set variable if you want to restrict the number of rows will be loaded
var maxStep = 0;//
// how many rows should be returned
var count = 100;
// if the cancel button is pressed
var cancel = false;
$(function() {
$('#load').click(function(){
getData();
})
$('#cancel').click(function(){
cancel = true;
})
});
function getData()
{
step++;
//If cancel variable is set to true stop new calls
if(cancel == true) return;
// checks if the variable is set and limits how many rows to be fetched
if(maxStep >0 and step >= maxStep) return;
$.post('ajax.php'
,{
'step':step,
'count':count,
}
,function(data, textStatus, jqXHR){
// do something with the data
// when it finishes processing the data, call back function
getData();
}
,'json'
)
}
AJAX.PHP
$step = 0;
if(isset($_POST['step'])) $step = (int)$_POST['step'];
$count = 0;
if(isset($_POST['count'])) $count = (int)$_POST['count'];
if($step>0 and $count>0)
{
$offset = ($step-1) * $count;
$limit = $offset.','.$count;
// --------------
// your code here
// --------------
$sql = "SELECT *
FROM $off_table,$cnt_table,$ctg_table
WHERE $off_table.id = $cnt_table.id
AND $off_table.id = $ctg_table.id
AND ".$cond_api."
AND ".$cond_nt."
AND ".$cond_cnt."
AND ".$cond_ctg."
LIMIT ".$limit;// <- limit
$result = mysql_query($sql);
$arr_result = array();
while($row = mysql_fetch_assoc($result))
{
$arr_result[] = $row;
}
$arr_result_enc = json_encode($arr_result);
echo $arr_result_enc;
// echo rows
echo json_encode($rows);
}
Here's a heavy refactoring of the client-side code, in which the overall process is split into into three separate functions getBatch(), makeRows() and showData(), and kicked off by a very modified version of the original click handler.
Batching is controlled by getBatch(), which makes a ajax requests with two extra params - start and batchSize. These instruct the server-side script which batch of data to return.
makeRows() and showData() are just synchronous worker functions called by getBatch().
I have assumed that progress is reported in a DOM element "#progress"`. You can report what you like here. I've kept it simple, showing the accumulated row count. By adding a batch counter, you could also show the number of completed batches.
Cancellation is achieved by setting outer var allowBatch to false. The currently requested batch will continue to be found but permission to retrieve further batches is withdrawn.
For good measure various DOM elements are enabled/disabled or shown/hidden at the start and end of the process. This can be omitted if not required.
var oTable;
$(document).ready(function() {
window.prettyPrint() && prettyPrint();
var aColumns = [],
columns = [],
rows = [],
$progress = $("#progress"),
allowBatch;
function getBatch(options) {
return $.post("ajax.php", options, 'json').then(function(data) {
var promise;
if(allowBatch && data && data.length) {
$progress.text(makeRows(data));
options.start += batchsize;
promise = getBatch(options);
} else {
promise = $.when(showData());
}
return promise;
});
}
function makeRows(data) {
var keycolumns, i, j;
if(aColumns.length == 0) {
keycolumns = Object.keys(data[0]);
for(j = 0; j < keycolumns.length; j++) {
if($.inArray(keycolumns[j], aColumns.sTitle) <= 0) {
aColumns.push({sTitle: keycolumns[j]});
columns.push(keycolumns[j]);
}
}
}
for(i = 0; i < data.length; i++) {
rows.push( columns.map(function(col) {
return data[i][col];
}) );
}
return rows.length;
}
function showData() {
var oTable = $('#jsontable').dataTable({
'columns': aColumns,
'sDom': 'T<"clear">lfrtip',
'oTableTools': {
"aButtons": [{
"sExtends": "csv",
"sButtonText": "CSV"
}]
}
});
oTable.fnClearTable();
$.each(rows, function(row) {
oTable.fnAddData(row);
});
return oTable;
}
$('#load').on('click', function(e) {
e.preventDefault();
var $load = $(this).attr('disabled', true),
$cancel = $("#cancel").show();
$progress.text('').show();
aColumns.length = columns.length = rows.length = 0;
allowBatch = true;
getBatch({
'version': $('#drp_v').val(),
'category': $('#drp_ctg').val(),
'country': $('#drp_cnt').val(),
'network_id': $('#drp_nt').val(),
'api': $('#drp_api').val(),
'func': 'show_datatable',
'start': 0,
'batchsize': 100
}).then(function(oTable) {
// ... all done
$load.attr('disabled', false);
$cancel.hide();
$progress.hide();
});
});
$("#cancel").on('click', function(e) {
e.preventDefault();
allowBatch = false;
}).hide();
$("#progress").hide();
});
Tested only for parse errors, so may need to be debugged
You will still need to modify the server-side script to accept the two additional parameter start and batchsize and compose its SQL accordingly. That should be fairly trivial.
The part I'm most uncertain about is makeRows(), which I struggled with slightly. If nothing works, look there first.
I am trying to take a set of text, and when I hit a button have it change to a different set of text. I have been trying a lot of different methods, and cannot seem to get it to work. Here is a working Jsfiddle.
I keep getting 'Uncaught TypeError: undefined is not a function' for the line
var $rep = $update.textContent.substring(1);
I have changed this line of code, but will the get the same error on a different line of code within the same function.
function createAnswers() {
var i;
for (i = 0; i < 4; i++) {
var $update = $(".answers p")[i];
var $rep = $update.textContent.substring(1);
console.log($rep);
var answerText = document.createTextNode(randomImage.randomAnswers[i]);
if (usedImages.length >= 1) {
$rep.replaceWith(answerText);
}
$update.appendChild(answerText);
}
}
I am still pretty new at Javascript, so I may be missing something very obvious. Any constructive criticism will be helpful.
Your function should look like:
function createAnswers() {
var i,
$answers = $(".answers p");
for (i = 0; i < 4; i++) {
var $update = $answers[i];
var $rep = $update.textContent.substring(1);
var answerText = document.createTextNode(randomImage.randomAnswers[i]);
if (usedImages.length >= 1) {
$update.textContent = $update.textContent.replace($rep, answerText.textContent);
}
$update.appendChild(answerText);
}
}
You do not need to use jQuery functions after var $update = $(".answers p")[i];, because $update becomes an DOM node.
I figured it out. Thanks everybody for the help. I realized I needed to specify the use of text nodes, and updating the text node directly. Here is my final code:
function createAnswers() {
var i,
$update;
for (i = 0; i < 4; i++) {
$update = $(".answers p")[i];
console.log($update);
var answerText = document.createTextNode(randomImage.randomAnswers[i]);
if (usedImages.length === 0) {
$update.appendChild(answerText);
}
else {
$update.childNodes[1].nodeValue = randomImage.randomAnswers[i];
}
}
}
I have the following code:
PHP code:
$data = array();
$data[0]['name'] = "Kj";
$data[0]['age'] = 30;
$data[0]['country'] = "Italy";
$data[1]['name'] = "Dn";
$data[1]['age'] = 18;
$data[1]['country'] = "USA";
$data[2]['name'] = "Jo";
$data[2]['age'] = 22;
$data[2]['country'] = "Switzerland";
$data[3]['name'] = "Ro";
$data[3]['age'] = 34;
$data[3]['country'] = "UAE";
$data[4]['name'] = "Lc";
$data[4]['age'] = 13;
$data[4]['country'] = "UK";
echo json_encode($data);
Javascript code:
var jsonData = {};
$(document).ready(function () {
$.get('page.php', function (data) {
jsonData = jQuery.parseJSON(data);
});
});
for (var i = 0; i < jsonData.length; i++) {
$('ul').append("<li>" + jsonData[i].name + "</li>");
}
The problem is when put the for loop inside the $.get callback works fine like as the following.
$.get('page.php', function (data) {
jsonData = jQuery.parseJSON(data);
for (var i = 0; i < jsonData.length; i++) {
$('ul').append("<li>" + jsonData[i].name + "</li>");
}
});
But when put the for loop outside the $.get callback does not print out anything, but the data has been received successfully, but without print it.
Now, how can store the data that has been received in global variable to print it in anywhere ?
You should change your approach when you work with asynchronous operations (AJAX, timeouts). Something like this:
function GetData(callback) {
$.get('page.php', function (data) {
callback(jQuery.parseJSON(data));
});
}
GetData(function (data) {
for (var i = 0; i < data.length; i++) {
$('ul').append("<li>" + data[i].name + "</li>");
}
});
Your code already stores data in a global variable correctly.
Type jsonData into F12-javascript console and you will see it.
The question is rather about the control flow, what is the other event that will trigger usage of jsonData?