Thursday, May 7, 2009

Disable submit button on form submit

Form submission is one of the most used actions and double form submission is one of most occurred problems in web development. Rather than dealing with this problem server side, eating up your CPU process time, it is much easier and better to deal with this problem client side using JavaScript. When we talk javascript, what it a better way to write it other than using jQuery?!

So this Friday’s quick tip is disabling form submit button on its click or preventing double form submission by disabling submit button.

Consider we have this HTML form in our code:

<form id="myform" action="someUrl.php" method="get">
    <input name="username" />
    <!-- some more form fields -->
    <input id="submit" type="submit" />
</form>

Here is a jQuery code that disables submit button on form submission:

$('#myform').submit(function(){
    $('input[type=submit]', this).attr('disabled', 'disabled');
});

The above jQuery code binds a submit event to our #myform form, then finds its submit button and disables it.

Bonus: disable submit button on form submission for all forms on your page.

// Find ALL <form> tags on your page
$('form').submit(function(){
    // On submit disable its submit button
    $('input[type=submit]', this).attr('disabled', 'disabled');
});
Want to disable any other elements using jQuery? Read my previous “Disabling and enabling elements in jQuery” (very short) post.

13 comments:

  1. i would prefer to block to block the whole screen with an overlay...

    ReplyDelete
  2. Alternative: Use a listerer, go to a custum utility object/method which does the submit, hook in a clickshield there.

    ReplyDelete
  3. For those who prefer blocking user interface with an overlay just like Michael Moossen suggested, I would recommend reading this post to easily achieve that.

    ReplyDelete
  4. It's worth noting, as always, that you should still code defensively and be able to deal with the double-submission scenario.

    Someone might visit your page with JS disabled; there could be a JS error earlier on, which prevents your submit handler from being executed, etc.

    But overall, I like this as a nice clean solution to prevent the majority of double-submits and I will include it in my projects. Thanks!

    ReplyDelete
  5. Thanks for this post, I've decided to disable everything I can before submission. Your code would not prevent double submissing by hitting ENTER key on some input.

    // Prevent form double-submission
    $('form').submit(function(){
    $('input[type=submit]', this).attr('disabled', 'disabled');
    $('select', this).attr('disabled', 'disabled');
    $('input[type=text]', this).attr('readonly', 'readonly');
    $('textarea', this).attr('readonly', 'readonly');
    });


    This code should probably appear inside a $(document).ready

    ReplyDelete
  6. I tried this but it prevented the button name being submitted (I had 2 buttons, save and cancel)

    So I tried...

    $('form').submit(function() {
    if(typeof $(this).data('submitted') == 'undefined') {
    $(this).data('submitted', 1);
    } else {
    return false;
    }
    });

    ReplyDelete
  7. For my purpose it's fantastic, does what it should, nothing less and nothing more.

    I don't see accidentally hitting the enter button twice a real issue in most applications but a valid point.

    In saying that I wouldn't include jQuery just for that 1 function... as I'm already calling jQuery for other functions however it suits me perfectly.

    Thanks for the tip!

    ReplyDelete
  8. This has problem: the button values won't get in the submit data if they are disabled.

    You can work around with with a timeout, eg:

    $('#myform').submit(function(){
    var self = this;
    setTimeout(function() {
    $('input[type=submit]', self).attr('disabled', 'disabled').css({color:"gray"});
    }, 1);
    });

    ReplyDelete
  9. The problem with the disabled aproach is that the input type=submit is not being post to the server.
    Some times you have many submit inputs on your form that you need to be posted to your server.

    ReplyDelete
  10. Better to bind the click event to return false

    $('form').submit(function(){
    $('input[type=submit]', this).click(function(){
    return false;
    });
    });

    ReplyDelete
  11. This solution must come with a cautionary note. It does not take care of scenarios of network latency/server failures (esp. for Ajax Form Submissions). So there might be cases when the request failed and the submit button is disabled; leaving no the user with no other choice but to refresh the browser window (...and possibly refill the form again).

    ReplyDelete
  12. You can also disable the form, adding to itself a class and capturing the submit event. Then, if the form has this class, you return false to ignore the submission

    $(document).ready(function() {
    $("form").submit(function(){
    if ($("body").hasClass('sendingForm')) {
    return false;
    }
    $("body").addClass('sendingForm');
    $(this).find("input:submit").css({visibility: "hidden"});
    $(this).find("input:button").css({visibility: "hidden"});
    $(this).find("a").css({visibility: "hidden"});
    $(this).find("input:submit").parent().append("Enviando...");
    return true;
    })
    });

    (As seen in http://www.adrformacion.com/articulos/javascript/evitar_reenvio_de_formularios_html_con_jquery/articulo1478.html )

    ReplyDelete
  13. Just a note it's nice to tweak the value so they know it's disabled:


    $('#paymentForm').submit(function(){
    $('#submit').attr({
    disabled: 'disabled',
    value: 'Processing, Please Wait...'
    });
    });

    ReplyDelete