changing values of array elements in javascript functions - php

These are my three functions that I am using in javascript :
function postRequest()
{
var xmlHttp;
if(window.XMLHttpRequest)
{ // For Mozilla, Safari, ...
var xmlHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{ // For Internet Explorer
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open('GET', 'effort.php', true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4)
{
get_string(xmlHttp.responseText);
dij();
}
}
xmlHttp.send(null);
}
function get_string(str)
{
get_integer = str.split(" ");
for(var i=0;i<214;i++)
{
vertex_i[j] = get_integer[i]*1;
j++;
}
j=0;
for(var i=214;i<427;i++)
{
vertex_f[j] = get_integer[i]*1;
j++;
}
j=0;;
for(var i=427;i<517;i++)
{
x[j] = get_integer[i]*1;
j++;
}
j=0;
for(var i=517;i<607;i++)
{
y[j] = get_integer[i]*1;
j++;
}
for(var m=0;m<90;m++)
{
for(var n=0;n<90;n++)
{
L[m][n] = -1;
}
}
for(var m=0;m<212;m++)
{
x1 = x[vertex_i[m]];
x2 = x[vertex_f[m]];
y1 = y[vertex_i[m]];
y2 = y[vertex_f[m]];
L[vertex_i[m]][vertex_f[m]] = parseInt(find_dist(x1,x2,y1,y2));
}
}
function point_it(event)
{
postRequest();
}
namely :
point_it(event),then postRequest(); and finally dij();
In these functions I use the data in three globally defined arrays,the elements of whose are derived from the data sent by the server(get_string function).
if I call dij() function from within the postRequest() function(after the get_string function I am able to access the correct data within the arrays.
However if I call it immediately after the postRequest() function the value of elements in the array become equal to null.
I am unable to understand the proper reason for this and have tried several ways to get through but with no progress.
CAn sm1 please help me out !

postRequest fires an asynchronous request to the server. Calling a function directly after it doesnt mean that the request has finished and youve doen anything with the response data. It works inside postRequest because that where you actually handle processing the request and response.
if you want to do this all from within point it i would recommend doing the following:
function postRequest(callback)
{
var callbackFunc = callback||null;
var xmlHttp;
if(window.XMLHttpRequest)
{ // For Mozilla, Safari, ...
var xmlHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{ // For Internet Explorer
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open('GET', 'effort.php', true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4)
{
get_string(xmlHttp.responseText);
if(callbackFunc){
callbackFunc();
}
}
}
xmlHttp.send(null);
}
function point_it(event)
{
postRequest(dij);
}
this allows you to vary the callback that uses the array thats been populated by the post request and in a away that it always fires after that request cycle is complete.

XMLHttpRequest is asynchronous.
That means, it will return as soon as the request was send. If you now call dij() the request will still be pending and get_string wasn't called yet.
As soon as the requests completes, the callback will be called, and then execute get_string.
You need to leave dij() inside the callback too.
Visually:
postRequest is made, sets the callback, but does not execute it, postRequest then returns
the code after the call to postRequest executes
some time passes...
the XMLHttpRequest finally completes and the callback executes, which now calls get_string

Global variables are not a good practice. It is better to combine your get_string and dij functions into one with your arrays as local variables inside the single function.

Related

Uploading indexedDB data to PHP in a loop

I am trying to use indexedDB to store offline data, and then upload the data when connected. In the following code a loop is used to read the data from indexedDB, and for each record (object) in the table (store), a JSON object is created and posted to a PHP file. However, this indexedDB loop only executes once. Is this because the JSON object was sent to server asynchronously?
var trans = LocalDB.indexedDB.db.transaction(storename,
IDBTransaction.READ_WRITE);
var store = trans.objectStore(storename);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
var obj = new Object;
obj.name = result.value.Name;
obj.Date = result.value.Date;
if (window.XMLHttpRequest)
xmlhttp = new XMLHttpRequest();
else
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
alert(xmlhttp.responseText);//problem: only shown once
result.continue();
}
};
xmlhttp.open("POST", "upload.php");
xmlhttp.setRequestHeader("Content-type", "application/json", true);
xmlhttp.send(JSON.stringify(obj));
};
cursorRequest.onerror = function (e) { alert("Error uploading"); };
If you check your Console for errors, you'll probably see an:
Uncaught Error: TransactionInactiveError
This does seem to be due to the Ajax request delaying the result.continue(). In the meantime, the transaction apparently becomes inactive and can no longer be used by the cursor.
You'll want to move the result.continue() out of the onreadystatechange:
// ...
xmlhttp.send(JSON.stringify(obj));
result.continue();
You could also opt for Sjax (synchronous). But, that's not generally recommended.
Also, note that the onsuccess callback will be called an additional time with a null result to signify the cursor has completed, so you'll want to test for this:
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
if (!result) {
console.log('Done');
return; // exit callback
}
// ...
};
You could also use this to send the entire collection in an Array with a single Ajax request:
var storedCollection = [];
cursorResult.onsuccess = function (e) {
var result = e.target.result;
if (result) {
storedCollection.push(result.value);
result.continue();
return; // exit callback
}
// else: the cursor is "done"
var xmlhttp = new XMLHttpRequest();
// ...
xml.send(JSON.stringify(storedCollection));
};
Example: http://jsfiddle.net/CZBrd/ (check Console)

Ajax / PHP updating DIV

I'm using the following to update a DIV called 'output'. This works fine with one exception, I would like echo entries to update the parent page.
<script type="text/javascript">
<!--
var divid = 'output';
var loadingmessage = '<img src="working.gif">';
function AJAX(){
var xmlHttp;
try{
xmlHttp=new XMLHttpRequest(); // Firefox, Opera 8.0+, Safari
return xmlHttp;
}
catch (e){
try{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); // Internet Explorer
return xmlHttp;
}
catch (e){
try{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
return xmlHttp;
}
catch (e){
alert("Your browser does not support AJAX!");
return false;
}
}
}
}
function formget(f, url) {
var poststr = getFormValues(f);
postData(url, poststr);
}
function postData(url, parameters){
var xmlHttp = AJAX();
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState > 0 && xmlHttp.readyState < 4){
document.getElementById(divid).innerHTML=loadingmessage;
}
if (xmlHttp.readyState == 4) {
document.getElementById(divid).innerHTML=xmlHttp.responseText;
}
}
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", parameters.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.send(parameters);
}
function getFormValues(fobj)
{
var str = "";
var valueArr = null;
var val = "";
var cmd = "";
for(var i = 0;i < fobj.elements.length;i++)
{
switch(fobj.elements[i].type)
{
case "select-one":
str += fobj.elements[i].name +
"=" + fobj.elements[i].options[fobj.elements[i].selectedIndex].value + "&amp;";
break;
}
}
str = str.substr(0,(str.length - 1));
return str;
}
//--></script>
This is called using :
<input type='button' name='Send' value='submit' onclick="javascript: formget(this.form, 'foo.php');">
The issue I have is foo.php runs a series of exec() commands, between each command is an echo statement that I would like to be displayed in the output div.
So it will do something like:
echo "archive files";
exec ("tar -cvf bar.tar bar.txt foo.txt");
echo "backing up /user";
exec ("tar -cvf /user.tar /user/*");
I would like the user to see the working.gif, but under it each echo statement from foo.php
Can that be done and how ?
Thanks
I can't say I've ever tried sending back chunks of data at separate times with a single AJAX request, so I'm not sure it's possible. What happens currently? Do you only get first echoed message, or do only get the entire response at the end?
Two things that I know will work:
Break your PHP script into multiple scripts and execute them in order with separate AJAX requests. This will only work if the separated scripts don't depend on each other or you find some other way to persist the state across the separated scripts.
Create an iframe and load the PHP script into it instead of using an AJAX request. Flushing the output of the PHP script should then work. (If you have ever used Wordpress, I believe they use this technique to show the progress of plugin updates.)

Sending two Ajax requests to two different PHP scripts from single javascript function

Is it possible to send Ajax requests to two or more Php scripts simultaneously? I know that this can be achieved serially (getting response from 1 and then getting response from the other) but I am wondering is it possible simultaneously. Please assist me with the following code:
function calShowUpload(){
if (http.readyState == 4) {
res = http.responseText;
document.getElementById('maincontent').innerHTML=res;
}
}
function showUpload(obj)
{
http.open("GET", "./showUpload.php", true);
http.onreadystatechange = calShowUpload;
http.send(null);
}
function getXHTTP() {
var xhttp;
try { // The following "try" blocks get the XMLHTTP object for various browsers…
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e2) {
// This block handles Mozilla/Firefox browsers...
try {
xhttp = new XMLHttpRequest();
}
catch (e3) {
xhttp = false;
}
}
}
return xhttp; // Return the XMLHTTP object
}
var http = getXHTTP(); // This executes when the page first loads.
In the above example I know that I can call another function like showUpload(obj) inside calShowUpload() to achieve my objective, but I need something like this:
function showUpload(obj)
{
http.open("GET", "./showUpload.php", true);
http.open("GET", "./showDelete.php", true);
http.onreadystatechange = calShowUpload;
http.send(null);
}
You need two instances of the XMLHttpRequest or the second will stomp the first. The very, very easiest way to do this with your existing code is simply to create two instances and write your JS to use whichever one is appropriate to the task.
var http1 = getXHTTP(); // Use this for one request.
var http2 = getXHTTP(); // Use this for the other request.

Using two xmlhttprequest calls on a page

I have two divisions, <div id=statuslist></div><div id=customerlist></div>
The function sendReq() creates a xmlhttprequest and fetches the data into the division.
sendReq('statuslist','./include/util.php?do=getstatuslist','NULL');
sendReq('customerlist','emphome.php?do=getcustomerlist','NULL');
I have a problem,
The data fetched into the 'customerlist' gets copied onto 'statuslist'
If i change the order of function calls,
sendReq('customerlist','emphome.php?do=getcustomerlist','NULL');
sendReq('statuslist','./include/util.php?do=getstatuslist','NULL');
Now the data of 'statuslist' gets into 'customerlist'..
Whats the problem with the code?
That's also my problem right now. After a thorough research, I've found out that:
If you have more than one AJAX task on your website, you should create ONE standard function for creating the XMLHttpRequest object, and call this for each AJAX task
- W3Schools.com
Also, thanks to Two xmlHttpRequests in a single page which redirects me to this question Using two xmlhttprequest calls on a page, I was able to solve the problem. By the way, it is a modification of Addsy's answer.
First, create a ONE standard function for creating the XMLHttpRequest object, and call this for each AJAX task. Example:
function sendReq(url, callbackFunction)
{
var xmlhttp
if (window.ActiveXObject)
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4 && xmlhttp.status=='200')
{
if (callbackFunction) callbackFunction(xmlhttp.responseText);
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
Second, call the function and pass the necessary parameters. For example:
sendReq("orders_code_get.php?currentquery="+sql, function processResponse( response )
{
document.getElementById("orders_content").innerHTML="";
document.getElementById("orders_content").innerHTML=response;
});
I have proven and tested this code and it works.
I have had this before.
Basically you have a scope problem - you have something like this in your sendReq() function?
if (window.ActiveXObject)
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
And so when you make a second request, the xmlhttp object is over-ridden
You need to create a closure where your xmlhttp objects don't clash
eg
function sendReq(url, callbackFunction)
{
var xmlhttp
if (window.ActiveXObject)
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
... probably some other stuff here, setting url etc ...
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4&&xmlhttp.status='200')
{
if (callbackFunction) callbackFunction(xmlhttp.responseText);
}
}
.. probably more stuff here ( including xmlhttp.send() ) !! ...
}
you can then pass the callback function as a parameter and when the data is successfully loaded, it will be passed to the callback function. Note that you will need to pass the actual function, not just its name (so no quotes around the function name)
Alternatively, you could do what i do which is just use jQuery - works for most of my js problems ;)
Hope this helps
In fact it is possible to run multiple async xhr call but you have to give them an unique id as parameter to be able to store and load them locally in your DOM.
For example, you'd like to loop on an array and make a ajax call for each object. It's a little bit tricky but this code works for me.
var xhrarray={};
for (var j=0; j<itemsvals.length; j++){
var labelval=itemsvals[j];
// call ajax list if present.
if(typeof labelval.mkdajaxlink != 'undefined'){
var divlabelvalue = '<div id="' + labelval.mkdid + '_' + item.mkdcck + '" class="mkditemvalue col-xs-12 ' + labelval.mkdclass + '"><div class="mkdlabel">' + labelval.mkdlabel + ' :</div><div id="'+ j +'_link_'+ labelval.mkdid +'" class="mkdvalue">'+labelval.mkdvalue+'</div></div>';
mkdwrapper.find('#' + item.mkdcck + ' .mkdinstadivbody').append(divlabelvalue);
xhrarray['xhr_'+item.mkdcck] = new XMLHttpRequest();
xhrarray['xhr_'+item.mkdcck].uniqueid=''+ j +'_link_'+ labelval.mkdid +'';
console.log(xhrarray['xhr_'+item.mkdcck].uniqueid);
xhrarray['xhr_'+item.mkdcck].open('POST', labelval.mkdajaxlink);
xhrarray['xhr_'+item.mkdcck].send();
console.log('data sent');
xhrarray['xhr_'+item.mkdcck].onreadystatechange=function() {
if (this.readyState == 4) {
console.log(''+this.uniqueid);
document.getElementById(''+this.uniqueid).innerHTML = this.responseText;
}
};
}
}
You have to set each xhr object in a global variable object and define a value xhrarray['xhr_'+item.mkdcck].uniqueid
to get its unique id and load its result where you want.
Hope that will help you in the future.

How to pass a javascript object array to php using POST

Lets say I have an array of javascript objects, and I am trying to pass those objects to a php page to save them into a database. I have no problems passing a variable to the php and using $_POST["entries"] on that variable but I can't figure out how to pass an entire array of objects, so I can access my objects.entryId and .mediaType values on the php page.
Oh and before anyone asks, yes the reason I need to do it this way is because I have a flash uploader, that you guessed it.. uploads into a CDN server (remote) and the remote server only replies back with such js objects.
Thanks for any help anyone can provide.
Here is my JS functions:
function test() {
entriesObj1 = new Object();
entriesObj1.entryId = "abc";
entriesObj1.mediaType = 2;
entriesObj2 = new Object();
entriesObj2.entryId = "def";
entriesObj2.mediaType = 1;
var entries = new Array();
entries[0] = entriesObj1;
entries[1] = entriesObj2;
var parameterString;
for(var i = 0; i < entries.length; i++) {
parameterString += (i > 0 ? "&" : "")
+ "test" + "="
+ encodeURI(entries[i].entryId);
}
xmlhttp.open("POST","ajax_entries.php",true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.setRequestHeader("Content-length", parameterString.length);
xmlhttp.setRequestHeader("Connection", "close");
xmlhttp.onreadystatechange = handleServerResponseTest;
xmlhttp.send(parameterString);
}
function handleServerResponseTest() {
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
alert(xmlhttp.responseText);
}
else {
alert("Error during AJAX call. Please try again");
}
}
}
maybe you need to take a look at json and jQuery ajax methods:
.- http://blog.reindel.com/2007/10/02/parse-json-with-jquery-and-javascript/
.- http://us.php.net/json_decode
The turorial is maybe a little outdated because jQuery last version is 1.3.x but you will get an idea on that and about the PHP json functions... if your server does not have the json extension enabled you can use some php classes:
.- http://google.com.co/search?rlz=1C1GPEA_enVE314VE314&sourceid=chrome&ie=UTF-8&q=php+json+class
good luck!
I too had the same trouble. But googling dint help.
I tried myself to tweak and test. And I got it. I am using POST method though. Please try the idea with GET method. Here is the idea:
Append the array index value within square brackets to the Post/Get variable name for array. Do this for each array element.
The part var parameters="&Name[0]="+namevalue1+"&Name[1]="+namevalue2; of the following script would give you a hint.
This is the test JS, I used (Again this uses POST method not GET):
var xmlAJAXObject;
function test() {
xmlAJAXObject=GetxmlAJAXObject();
if (xmlAJAXObject==null) {
alert ("Oops!! Browser does not support HTTP Request.");
return false;
}
var namevalue1=encodeURIComponent("Element 1");
var namevalue2=encodeURIComponent("Element 1");
var parameters="&Name[0]="+namevalue1+"&Name[1]="+namevalue2;
xmlAJAXObject.open("POST", "test.php", true);
xmlAJAXObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlAJAXObject.setRequestHeader("Content-length", parameters.length);
xmlAJAXObject.onreadystatechange=stateChanged;
xmlAJAXObject.send(parameters);
}
function stateChanged() {
if (xmlAJAXObject.readyState ==4) {
if (xmlAJAXObject.status == 200) {
alert('Good Request is back');
document.getElementById("show").innerHTML=xmlAJAXObject.responseText;
}
}
}
function GetxmlAJAXObject() {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject) {
// code for IE6, IE5
return new ActiveXObject("Microsoft.Microsoft.XMLHTTP");
}
return null;
}
This worked for me. Sorry for the formatting and incomplete code. I meant to give a direction. Google reault websites couldn't give a solution. Hope you find this useful.

Categories