Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
241 views
in Technique[技术] by (71.8m points)

javascript - jQuery: Submit a form only if no AJAX is currently running on the page

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.

$(document).ready(function() {
    var ajaxBusy = false;

    $(document).ajaxStart( function() { 
        ajaxBusy = true; 
    }).ajaxStop( function() {
        ajaxBusy = false;
    });
});

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.

$('input#city').on('blur', function() {
    var submit = $(this).closest('form').find(':submit:enabled');
    submit.prop('disabled', true);
    $.ajax('get/something?param=val').done(function(response) {
        $('input:hidden[name="something"]').val(response);
    }).always(function() {
        submit.prop('disabled', false);
    });
});

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.

$(document).ready(function() {
    var ajaxDefer = $.Deferred().resolve();

    $(document).ajaxStart( function() { 
        ajaxDefer = $.Deferred(); 
    }).ajaxStop( function() {
        ajaxDefer.resolve();
    });

    $('form#find-users').on('submit', function() {
        ajaxDefer.always(function() {
            // Code here will always be executed as soon as there are no 
            // Ajax calls running.
            // this points to the deferred object (ajaxDefer), so use the closure
            // to carry over any variables you need.
        });
    });
});
  1. When we're just starting out, we set up our ajaxDefer object in a resolved state. That means any functions attached using .always() will execute immediately.

  2. When the first Ajax call starts, we replace the old ajaxDefer object with a new one that has not been resolved. Any new functions attached using ajaxDefer.always() will be deferred until later.

  3. 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.

  4. 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...