Reputation: 43778
Any one know how can I display the loading progress with completed % on my client side while the system is still getting data in the server side.
For example, when I press 'ok' button in the client side, it will call to server side to collect data from the database, the whole process may take 2 to 3 mins. How can I display the loading progress on the client side (about how many % of the loding have been done)?
How can I do it in php, ajax or javascript?
Upvotes: 2
Views: 4050
Reputation: 1235
I needed the same thing done - tracking Ajax data download progress - so I'll post a solution that I used in case someone bumps into this thread:
var req = new XMLHttpRequest();
req.addEventListener("progress", onUpdateProgress, false);
req.addEventListener("load", onTransferComplete, false);
req.addEventListener("error", onTransferFailed, false);
req.addEventListener("abort", onTransferAborted, false);
req.open("GET", ..., true);
...
req.send()
function onUpdateProgress(e) {
if (e.lengthComputable) {
var percent_complete = e.loaded/e.total;
document.getElementById("progressMessage").value = Math.round(percentComplete*100) +"% [ " + Math.round(e.loaded / 1000) + " KB ]";
...
} else {
// Length not known, to avoid division by zero
}
}
function onTransferComplete(e) { ... }
function onTransferFailed(e) { ... }
function onTransferAborted(e) { ... }
Upvotes: 3
Reputation:
multipart/x-mixed-replace; with flush should work in a stateless load balanced environment. The approaches that rely on periodic GET requests to check progress will not succeed in environments where subsequent requests might go to a different back end.
Upvotes: 0
Reputation: 18549
it's not that easy. if the ajax call starts the processing, you could do a chunked/multipart response (that's how most dhtml chats are implemented). google for "COMET".
basically it works like that:
echo
0%, flush();
(without script termination)echo
and flush();
i once (when async javascript was still new!) coded a little demo ... it's a bit defunct now, but the async part still works. you can find it here: http://wehrlos.strain.at/httpreq/client.html
the javascript clientside code used
function asSendSyncMulti() {
var httpReq = new XMLHttpRequest();
showMessage( 'Sending Sync Multipart ' + (++this.reqCount) );
// Sync - wait until data arrives
httpReq.multipart = true;
httpReq.open( 'GET', 'server.php?multipart=true&c=' + (this.reqCount), false );
httpReq.onload = showReq;
httpReq.send( null );
}
function showReq( event ) {
if ( event.target.readyState == 4 ) {
showMessage( 'Data arrives: ' + event.target.responseText );
}
else {
alert( 'an error occured: ' + event.target.readyState );
}
}
the serverside php code for the multipart part:
<?php
$c = $_GET[ 'c' ];
header('Content-type: multipart/x-mixed-replace;boundary="rn9012"');
sleep( 1 );
print "--rn9012\n";
print "Content-type: application/xml\n\n";
print "<?xml version='1.0'?>\n";
print "<content>Multipart: First Part of Request " . $c . "</content>\n";
print "--rn9012\n";
flush();
sleep( 3 );
print "Content-type: application/xml\n\n";
print "<?xml version='1.0'?>\n";
print "<content>Multipart: Second Part of Request " . $c . "</content>\n";
print "--rn9012--\n";
?>
it's nothing more than a nudge in a possible direction. not html-compliant or cross browsery. use json instead of xml.
on the server side, output caching (e.g. for compression) must be turned off, otherwise the flush();
won't do anything. and the --rn9012
should be something that never occures in your outputted data (unlikley if you just display progress but still).
Upvotes: 2
Reputation: 2972
jQuery can display a splash screen (div) while the ajax request is running. This can be done for each request with .ajaxStart and .ajaxEnd (or .ajaxStop) or a more complicated approach is to use Dojo's dojo.io.bind or follow the Periodic Refresh Pattern below.
Upvotes: 0
Reputation: 25147
Once you click on the "Ok" button, you could start fetching data server-side and keep the percentage loaded in the session.
That way, client-side you could make a request via AJAX to another php script returning the percentage loaded.
You would end up with 2 server-side scripts (one to fetch the data and other to fetch the percentage) and one AJAX request client side.
I think that's an easy solution and should do it fine.
Upvotes: 2
Reputation: 11736
I do this by paging the results.
First request is to get a count. Then break up the request into a set of groups. Then start requesting the groups one at a time.
For example: if there are 100 records to return, I break them up into groups of 10. Then I can easily display 10% ... 20%...etc
I don't know of anyway to do this.
Upvotes: 0