Jin Yong
Jin Yong

Reputation: 43778

Loading progress in php, ajax or javascript?

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

Answers (6)

Vuk
Vuk

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

johnlon
johnlon

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

stefs
stefs

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:

  1. client: ajax call requesting the start of the long running action
  2. server: start the long running action, echo 0%, flush(); (without script termination)
  3. client: recieves a response with the flushed content (special callback), displays the value and but the connection stays open!
  4. server: after x action calculate the percentage, echo and flush();
  5. client: see #3
  6. server: if the script is complete, terminate
  7. client: normal event/callback for end of script. display 100%, open next page

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

IEnumerator
IEnumerator

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.

Periodic Refresh

Upvotes: 0

Seb
Seb

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

Chris Brandsma
Chris Brandsma

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

Related Questions