Jump to content

Recommended Posts

Hi

 

At risk of looking liking an idiot here I feel. Here goes though! I have the following code. Only the one with 'row10' changes though. Everything else sticks on 'Loading...'. Looking at the Apache logs I can see it is requesting each page (wait.php?q=0.. waiting.php?q=1... and so on up to 10).

 

index.php

<html>
   <head>
     <title>This is a ajax test page</title>
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
     <script language="Javascript" type="text/javascript">
        function ajax(id) {
           for(var i=0;i<=id;i++) {
           rowid = 'row'+i;
           var xmlhttp;
           if (window.ActiveXObject) {
              xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
           } else {
              xmlhttp = new XMLHttpRequest();
           }
           xmlhttp.onreadystatechange = function() {
              if (xmlhttp.readyState == 3) {
              }
              if (xmlhttp.readyState == 4) {
                 document.getElementById(rowid).innerHTML = xmlhttp.responseText;
              }
           }
           document.getElementById(rowid).innerHTML = 'Loading...';
           xmlhttp.open('GET', 'wait.php?q='+i, true);
           xmlhttp.send(null);
           }
        }
</script>
</head>

<?PHP
$x = '10';
echo '<body onload="ajax('.$x.')">';

for( $y=0; $y<=$x; $y++ ){
echo ' <div id="row'.$y.'">#'.$y.'#</div>'.PHP_EOL;
}
?>

</body>

</html>

 

wait.php

<?PHP
$q = $_GET['q'];
sleep($q);
echo 'That should have taken '.$q.' seconds.';
?>

 

Can any one point out my mistake please? :)

 

Thanks

Shell

Edited by shelluk
Link to comment
https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/
Share on other sites

I think it's because of the asyn nature of AJAX. The xmlhttp.onreadystatechange is only executed when the the ajax call is ready. It will probably be that the for loop by then, is in the next loop. Therefore only in the last loop the ajax call is fully executed.

 

You can try by calling the ajax function again in the part where the responseText is received, therefore when the ajax call is finished, try this:

 

function ajax(y) {					  

var i = y;

rowid = 'row'+i;  
var xmlhttp;					   
if (window.ActiveXObject) {	 
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');				 
} else {				
xmlhttp = new XMLHttpRequest();	  
}				 
xmlhttp.onreadystatechange = function() {	
if (xmlhttp.readyState == 3) {			 
}					  
if (xmlhttp.readyState == 4) {	 
document.getElementById(rowid).innerHTML = xmlhttp.responseText;	  
ajax(i+1);
}				 

}							  
xmlhttp.open('GET', 'wait.php?q='+i, true);		
xmlhttp.send(null);				  

}</script></head>
<?PHP
$x = '10';
echo '<body onload="ajax(0)">';
for( $y=0; $y<=$x; $y++ ){
echo ' <div id="row'.$y.'">#'.$y.'#</div>'.PHP_EOL;
}?>
</body></html>

 

However, the seconds are 'wrong' now because you should count the 'delay' i guess..

That works, thanks stijn0713! :)

 

May be it's good to ask if I'm going around this the right way. The above is just an example for me to get my head around this (I'm new to Javascript/AJAX).

 

I have a variable amount of queries (and so divs), with each out putting to their own div to process. While each one is being processed (some queries could take 5 secs to process while some are instant), I want it to show 'Loading...' in the div rather than the whole page being on hold for 5 seconds (or 10 if 2 of them take 5 seconds to process for example).

 

Thank you

I'm not 100% sure what stijn meant with "it will probably be that the for loop by then", but the problem does indeed lie within the for loop. Or rather, how you're overwriting the xmlhttp variable for each iteration in that loop.

 

Once you overwrite it, you also remove the onreadystate call, and its associated function. Meaning, only the last iteration of the loop will stick around for long enough, and thus be the only iteration that actually produces the desired effect. The rest of the calls to the PHP script have been orphaned, and is summarily dropped/ignored upon reception.

 

To fix it, you either have to call a function per iteration, or generate a new variable. I recommend moving the loop outside of the function.

Actually stijn's didn't work as intended.

 

row 0 = 0 secs

row 1 = 1 secs

row 2 = 3 (2+1) secs

row 3 = 6 secs (3+2+1) secs

.. and so on

I want all to start at the same time. No waiting.

 

I'll take a closer look at what you said Christian. It's a shame div doesn't support an onload!

The wait.php with the wait is just for the purpose of demonstrating a delay which I might see in what I am going to try and achieve.

 

I think I've nailed it though, this looks like it does exactly what I want :) All queries get processed in quick succession, not after the last one completed.

 

<html>
<head>
	<title>This is a ajax test page</title>
	<script src="[url="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js%22></script>"]http://ajax.googleap...n.js"></script>[/url]
	<script language="Javascript" type="text/javascript">
		function gogo(x) {
			for(var y=0;y<=x;y++) {
				populate(y);
			}
		}

		function populate(i) {
			var xmlhttp;
			if (window.ActiveXObject) {
				xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
			} else {
				xmlhttp = new XMLHttpRequest();
			}
			xmlhttp.onreadystatechange = function() {
				if (xmlhttp.readyState == 4) {
					document.getElementById('row'+i).innerHTML = xmlhttp.responseText;
				}
			}
			document.getElementById('row'+i).innerHTML = 'Loading...';
			xmlhttp.open('GET', 'wait.php?q='+i, true);
			xmlhttp.send(null);
		 }
	</script>
</head>

<?PHP
$x = '10';
echo '<body onload="gogo('.$x.')">';

for( $y=0; $y<=$x; $y++ ){
echo ' <div id="row'.$y.'">#'.$y.'#</div>'.PHP_EOL;
}
?>

</body>

</html>

Edited by shelluk
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.