Prevent double submission of forms in jQuery

Update in 2018: I just got some points for this old answer, and just wanted to add that the best solution would be to make the operation idempotent so that duplicate submissions are harmless.

Eg, if the form creates an order, put a unique ID in the form. The first time the server sees an order creation request with that id, it should create it and respond "success". Subsequent submissions should also respond "success" (in case the client didn't get the first response) but shouldn't change anything.

Duplicates should be detected via a uniqueness check in the database to prevent race conditions.


I think that your problem is this line:

$('input').attr('disabled','disabled');

You're disabling ALL the inputs, including, I'd guess, the ones whose data the form is supposed to submit.

To disable just the submit button(s), you could do this:

$('button[type=submit], input[type=submit]').prop('disabled',true);

However, I don't think IE will submit the form if even those buttons are disabled. I'd suggest a different approach.

A jQuery plugin to solve it

We just solved this problem with the following code. The trick here is using jQuery's data() to mark the form as already submitted or not. That way, we don't have to mess with the submit buttons, which freaks IE out.

// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function() {
  $(this).on('submit',function(e){
    var $form = $(this);

    if ($form.data('submitted') === true) {
      // Previously submitted - don't submit again
      e.preventDefault();
    } else {
      // Mark it so that the next submit can be ignored
      $form.data('submitted', true);
    }
  });

  // Keep chainability
  return this;
};

Use it like this:

$('form').preventDoubleSubmission();

If there are AJAX forms that should be allowed to submit multiple times per page load, you can give them a class indicating that, then exclude them from your selector like this:

$('form:not(.js-allow-double-submission)').preventDoubleSubmission();

I think Nathan Long's answer is the way to go. For me, I am using client-side validation, so I just added a condition that the form be valid.

EDIT: If this is not added, the user will never be able to submit the form if the client-side validation encounters an error.

        // jQuery plugin to prevent double submission of forms
        jQuery.fn.preventDoubleSubmission = function () {
            $(this).on('submit', function (e) {
                var $form = $(this);

                if ($form.data('submitted') === true) {
                    // Previously submitted - don't submit again
                    alert('Form already submitted. Please wait.');
                    e.preventDefault();
                } else {
                    // Mark it so that the next submit can be ignored
                    // ADDED requirement that form be valid
                    if($form.valid()) {
                        $form.data('submitted', true);
                    }
                }
            });

            // Keep chainability
            return this;
        };

Timing approach is wrong - how do you know how long the action will take on client's browser?

How to do it

$('form').submit(function(){
  $(this).find(':submit').attr('disabled','disabled');
});

When form is submitted it will disable all submit buttons inside.

Remember, in Firefox when you disable a button this state will be remembered when you go back in history. To prevent that you have to enable buttons on page load, for example.