shelluk Posted January 15, 2013 Share Posted January 15, 2013 (edited) 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 January 15, 2013 by shelluk Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/ Share on other sites More sharing options...
stijn0713 Posted January 15, 2013 Share Posted January 15, 2013 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.. Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1405925 Share on other sites More sharing options...
shelluk Posted January 16, 2013 Author Share Posted January 16, 2013 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 Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1406068 Share on other sites More sharing options...
Christian F. Posted January 16, 2013 Share Posted January 16, 2013 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. Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1406070 Share on other sites More sharing options...
shelluk Posted January 16, 2013 Author Share Posted January 16, 2013 Hi Christian I did what stijn said and it did work. I did wonder before hand though and did try making xmlhttp an array. It didn't help though. Thanks Michelle Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1406073 Share on other sites More sharing options...
shelluk Posted January 16, 2013 Author Share Posted January 16, 2013 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! Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1406082 Share on other sites More sharing options...
stijn0713 Posted January 16, 2013 Share Posted January 16, 2013 if you just want to obtain the result, you can change sleep($q) to sleep(1). in your wait.php. But i would also have a look at what christian says, he's far more experienced than i am Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1406083 Share on other sites More sharing options...
shelluk Posted January 16, 2013 Author Share Posted January 16, 2013 (edited) 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 January 16, 2013 by shelluk Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1406086 Share on other sites More sharing options...
Christian F. Posted January 16, 2013 Share Posted January 16, 2013 Yep, that's it! Quote Link to comment https://forums.phpfreaks.com/topic/273199-updating-multiple-elementsfor-loop/#findComment-1406092 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.