views:

195

answers:

4

I'd like to show some visual progress to a user during an ajax request. E.g when he clicks a 'process' button which makes an AJAX request to a server-side script, he will see a 'loading...' message and a graphic, but I also want to show him some progress of how much processing is done. E.g 5/10 processed, 6/10 processed... and so on.

Is there anyway to do this?

+2  A: 

I don't know what your server side process actually is, but would it make any sense to break it up into a series of Ajax calls, each doing a part of the process? Then you could increment you display at each step.

Andrew
+1  A: 

jQuery + PHP example of progress bar implementation, polling server-side script for the percents remaining. click here

duckyflip
+1  A: 

In Safari 4 and Firefox 3.5, you can determine the progress of an XMLHttpRequest as follows:

var url = "[URL to file]";
var request = new XMLHttpRequest();

request.onprogress = function(e) {
    if (e.lengthComputable) {
     var percentComplete = (e.loaded / e.total) * 100;
     console.log("Progress: " + percentComplete + "%");
    }
    else {
     // Code to execute when we can't get the progress
    }
};

request.open("GET", url, true);
request.send("");

For more information, refer to this page at the Mozilla Developer Centre.

Steve

Steve Harrison
Thanks, but i was talking more about the operation happening on the serverside than the progress of the download of the ajax request
Click Upvote
+1  A: 

Yep, there is, but it is kind of complicated. The only way I've found is using an iframe on the client, and response.writeing on the server to send blocks of javascript back to the client, that javascript calls on the parent window to process the status messages.

Here's some sample code. There may be problems with it, I'm snipping it out of a much bigger app.

html:

<button id="doStuff">
<div id="status"></div>
<div id="iframeHolder"></div>

javascript:

//This one will be called from the HTML the javascript is streaming back
function updateStatus(message) {
    $('#status').html(message);
}
$('#doStuff').click(function(event) {
    event.preventDefault();
    var url="your.page.html";
    $('#iframeHolder').html('<iframe src="' + url + '"></iframe>');
}

server side (this is vb asp.net, but you should be able to do it in your language of choice):

dim message as string = "hello world"
dim script = String.Format("<script type='text/javascript'>parent.updateStatus('{0}');</script>",message)
Response.Write(script)

Some observations

  • Querystring will be your friend here. I'm not sure if you can programatically postback to an iframe
  • You will probably have to add some cachebusting garbage to the querystring, otherwise the browser will more than likely cache the contents. It'll be very very quick, but wrong :-)
  • You might need to send "some" html before the browser starts processing the iframe stuff. I've found that sending a HTML comment of about 1k of garbage helps
  • To avoid refresh problems in FF, and "forever loading" problems in chrome and safari, set the iframe's src to about:blank once you're done ($('#iframeHolder iframe').attr('src','about:blank'))
  • the jQuery UI progress bar looks pretty swanky for displaying the percent processed

Hope that helps. I tore my head out with this a couple of months ago :-)

Dan F