You need some kind of progress info from the server. The ajax callbacks do no progressive work, they fire just once - after the request returned successfully.
So... in PHP you would need something like this:
/* progress.php */
$batch_done = some_way_to_find_out_that_number();
$batch_size = some_way_to_find_out_that_number_too();
header('Content-type: application/json');
// TODO: format number
echo '{"progress":'. ($batch_size==0 ? '0' : $batch_done*100.0/$batch_size).'}';
For this to work your image processing script must leave some evidence of its progress of course.
And in JavaScript something like this:
$(document).ready(function() {
$('a.loop').click(function() {
var queryData = {foo:"bar"};
// prepare a function that does cyclic progress checking
var progressCheck = function() {
$.getJSON(
"progress.php", queryData,
function(data) {
$("div.progress").css("width", data.progress+"%");
}
)
};
$.post(
'loop.php', queryData,
/* create the post request callback now */
function(intvalId){
return function(data) {
$("div").html(data);
clearInterval(intvalId);
}
}( setInterval(progressCheck, 1000) )
);
return false;
});
});
This part requires some explanation:
function(intvalId){
return function(data) {
$("div").html(data);
clearInterval(intvalId);
};
}( setInterval(progressCheck, 1000) )
function(intvalId)
is an anonymous function that takes one argument - an interval ID. This ID is necessary to stop an interval that has been set up via setInterval()
. Luckily, the call to setInterval()
returns this very ID.
The anonymous outer function returns an inner function(data)
, this one will be the actual callback for $.post()
.
We call the outer function immediately, doing two things in the process: Triggering off the interval with setInterval()
and passing in its return value (the ID) as an argument. This argument value will be available to the inner function at its call time (which may be some minutes in the future). The callback for post()
now can actually stop the interval.
As an exercise for you ;)
- Modify the ajax call such that it stops the interval on request error or timeout, too. Currently, if the callback is never run (and it runs on success only!), the interval will never stop.
- Make sure the
post()
cannot be triggered twice inadvertently.