I've got quite a complex search which utilises multiple ajax calls, the flow is as follows:
user performs search on button click
ajax request is made to php page which returns json data
for each result in returned data additional ajax request is made
run function which makes additional ajax call
end for each
end click function
this all works nicely, what i would like to do is display a loading message in a div and disable the search button, then when all the ajax requests have completed re-enable the button and remove the loading message.
my script is below, at the moment the disable/renable of the button is happening almost instantaneously, i presume because the ajax calls are asyncronus, how do i go about renabling the button and removing the loading message once all the ajax requests have completed and displayed the data??
$('#advKeyBtn').live('click', function() {
$('#advKeyBtn').attr('disabled', 'disabled');
$('#searchStatus').html('<img src="../img/icons/loadinfo.gif" width="16" height="16" /> Searching Locations...');
$('#results').html(''); //clear existing contents
$('#borough_links').html(''); //clear existing contents
// handler for advance search button
var myUrl = 'getKeyBoroughs.php';
var myKeys = $('#keywords').val();
var myType = $('input[name=keyParams]:checked').val()
$.ajax({
url: myUrl,
data: "keys=" + myKeys +'&type='+myType,
type: "POST",
traditional: false,
dataType: 'json',
error: function(xhr, statusText, errorThrown){
// Work out what the error was and display the appropriate message
},
success: function(myData){
// data retrived ok
$.each(myData.boroughs, function( intIndex, objValue ){
//alert(myData.boroughs[intIndex].Borough_ID);
makeCSS(myData.boroughs[intIndex].Borough_ID);
getKeyLocations(myData.boroughs[intIndex].Borough_ID)
})
//$('#'+divId).append(myData)//construct location holders
}
});
$('#advKeyBtn').attr('disabled', '');
$('#searchStatus').html('Search Complete, click on an area to view locations');
});
and the function that gets called from the initial success of the main ajax call
function getKeyLocations(id){
var myUrl = 'getKeyLocations.php';
var myBorough = id;
var myKeys = $('#keywords').val();
var myType = $('input[name=keyParams]:checked').val()
var divId = '#borough_'+ id;
$.ajax({
url: myUrl,
type: 'POST',
data: 'borough_id='+myBorough+'&keys='+myKeys,
error: function(xhr, statusText, errorThrown){
// Work out what the error was and display the appropriate message
},
success: function(myData){
$(divId).html(myData);
}
});
};
jQuery ajaxStop() Method The ajaxStop() method specifies a function to run when ALL AJAX requests have completed. When an AJAX request completes, jQuery checks if there are any more AJAX requests. The function specified with the ajaxStop() method will run if no other requests are pending.
You can store your promise, you can pass it around, you can use it as an argument in function calls and you can return it from functions, but when you finally want to use your data that is returned by the AJAX call, you have to do it like this: promise. success(function (data) { alert(data); });
There is a requirement to make multiple AJAX calls parallelly to fetch the required data and each successive call depends on the data fetched in its prior call. Since AJAX is asynchronous, one cannot control the order of the calls to be executed.
success() only gets called if your webserver responds with a 200 OK HTTP header - basically when everything is fine. However, . complete() will always get called no matter if the ajax call was successful or not - maybe it outputted errors and returned an error - . complete() will still get called.
You have to create a function that will handle all your requests. When all requests are finished then enable the button and show the message.
var ajaxLoading = {
_requestsInProcess: 0,
show: function () {
if (this._requestsInProcess == 0) {
$('#advKeyBtn').attr('disabled', 'disabled');
$('#searchStatus').html('<img src="../img/icons/loadinfo.gif" width="16" height="16" /> Searching Locations...');
}
this._requestsInProcess++;
},
hide: function () {
this._requestsInProcess--;
if (this._requestsInProcess == 0) {
$('#advKeyBtn').attr('disabled', '');
$('#searchStatus').html('Search Complete, click on an area to view locations');
}
}
};
now, before all ajax call use:
ajaxLoading.show()
And in all your success methods use:
ajaxLoading.hide()
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With