When the city input field is blurred I get somnething via an ajax request and set that as the value of a hidden field in the same form that the city field resides in.
$('input#city').on('blur', function() {
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
}
});
});
If the user submits the form immediately after blurring off the city field sometimes due to latency the hidden field is not populated because the SQL on the other end is taking too long.
The form that both these fields are in is also submitted via ajax:
$('form#find-users').on('submit', function() {
if(NO_AJAX_CURRENTLY_RUNNING_ON_PAGE) {
// do stuff
}
});
How to detect if no ajax is running on the page? This will ensure that the city ajax was completed and the hidden field populated before the form is processed.
EDIT
Actually it won’t, it will only prevent the form from being submitted. But if I can detect that then I can use a setInterval and keep trying to run that code until it runs because ajax is complete. Ideally there will be something in jQuery that waits until other ajax is complete and then submits.
Use jQuery’s Ajax Events. As long as all of your Ajax calls are generated using jQuery, you have a way of knowing if any Ajax calls are outstanding.
Edit:
So that answers your direct question about “How do I know if there is any Ajax call running.”
Alternatively, you could disable the form’s submit buttons when run your blur handler, and then re-enable it when you’re done.
Edit 2:
So now we’re at the point where we would like to delay the form submission until all current Ajax calls have completed. We let people click on the submit button, but if there are pending Ajax calls we don’t do anything right away.
We can use a Deferred object to help us with this.
When we’re just starting out, we set up our
ajaxDeferobject in a resolved state. That means any functions attached using.always()will execute immediately.When the first Ajax call starts, we replace the old
ajaxDeferobject with a new one that has not been resolved. Any new functions attached usingajaxDefer.always()will be deferred until later.When the last Ajax call completes, we call
ajaxDefer.resolve(), which causes any unexecuted deferred functions to execute. Now we’re back to our initial state, where any newly-attached functions will execute immediately.When somebody tries to submit the form, create an anonymous function that does the work and attach it to
ajaxDefer. It will get executed when appropriate, depending on if there are any outstanding Ajax requests or not. Be mindful of your closures.