Recently I ran into a problem for a website that I develop that connects to MSSQL and retrieves (lots) of data and got somewhat slow on loading.
I wanted to give the user a ‘wait for loading’ message while the data was retrieved.
Starting point:
I’m using AJAX to be able to keep te main page (instead of refreshing all every time a POST request is made).
I’m NOT using any other javascript libraries (mainly because I like living without the overhead of those, the updates they require and the new syntax I have to get familiar with).
Problem:
Sometimes the MSSQL data returned ‘too’ quickly and the load message was displayed later (hence, replacing the MSSQL data), so I had to find a way to make sure the MSSQL data was only returned after the ‘load’ message was there.
Since AJAX is asynchronous, javascript will NOT wait for it….
Example of the ‘problem’
https://www.tricks-and-tips.nl/loadTest/test.php
I have created a simplified version that shows the problem:
1. test.php
[code language=”html”]
<html>
<head>
<script type=’text/javascript’ src=’ajax.js’></script>
<script type=’text/javascript’>
test(‘test’,1);
test(‘test’,2);
</script>
</head>
<body>
<div id=’test’>
</div>
</body>
<html>
[/code]
So here we call the function ‘test’ two times, with different parameters.
This function just replaces the content of a specific div.
2. test.js
[code language=”javascript”]
function test(
div
,fnr
)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById(div).innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("POST","testLoad"+fnr+".php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=utf-8");
xmlhttp.send(
"div="+div
);
}
[/code]
Basically the function makes a POST to a specific PHP file (where the MSSQL tables will be generated) and puts the response in the div from the test.php
3. testLoad1.php
[code language=”php”]
<?php
for($i=1;$i<=10000000;$i++){
//Some loop to take some time
}
echo "This is the wait message, should only appear while waiting for the second php request.";
?>
[/code]
Some example php that takes some time to load and return a text.
4. testLoad2.php
[code language=”php”]
<?php
echo "This is the actual data, returned by MSSQL / PHP";
?>
[/code]
The second PHP file that will return the MSSQL data. (or MySQL)
In our example the first php file takes longer to load than the second (deliberately caused by the long loop in the first php file), replicating our real problem.
Just look at the example in
https://www.tricks-and-tips.nl/loadTest/test.php
First you see the ‘actual data’…
After a short while the first AJAX call is finished and replaces the ‘right’ data with the load message…
Not what we like.
Solution
I did some research and there is a lot documentation on a ‘callback’ from a function, but in my case I ended up making a simple modification to my test.js
[code language=”javascript”]
function test(
div
,fnr
)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById(div).innerHTML=xmlhttp.responseText;
//Ready, now load another function (or the same, with differen parameters)
test(div,2);
}
}
xmlhttp.open("POST","testLoad"+fnr+".php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded;charset=utf-8");
xmlhttp.send(
"div="+div
);
}
[/code]
Now on line 23 you see a new call to the same function (only with a different parameter 2)
This only gets fired when the readyState = 4 and the status = 200 (OK)
And, of course, we now only called the function ‘test’ one time:
[code language=”html”]
<html>
<head>
<script type=’text/javascript’ src=’test.js’></script>
<script type=’text/javascript’>
//Call the ‘test’ function in test.js
test(‘test’,1);
</script>
</head>
<body>
<div id=’test’>
</div>
</body>
<html>
[/code]
To view an example of the ‘working’ code:
https://www.tricks-and-tips.nl/loadTest2/test.php
I am still working on the final code, to make it ‘generic’, but If you have any questions, feel free to ask!