1

I am trying to adapt a bunch of existing web apps to prevent users from accidentally bouncing on the submit button and submitting the form twice. I thought jquery would be the best way to do this, although my pages use very little jquery otherwise.

I've found many similar questions here, and the answers have been very useful but still do not offer a complete and simple solution. The first solution I hit upon was this:

$(document).ready(function(){
    $('form').submit(function(){
         $("input[type=submit]").prop("disabled", true);
    });
});

It works very well, greying out the submit button(s) after the form is submitted. The problem is that the value of the submit button itself does not get submitted with the form, I guess because it is disabled. Usually that is not a problem, but for some of the applications it is because they depend on the value of the submit button for correct operation. I would like something more general that will work for those pages without having to redesign them.

I then tried this other example:

$(document).ready(function(){
  $('form').submit(function(){
    $(this).submit(function() {
      return false;
    });
    return true;
  });
});

This works well for disabling multiple submissions while still transmitting the value of the submit button, but it does not grey out the submit button, so there is no visual indication that the submission has occured. I will probably go with if I cannot find a better solution, but I would like both to transmit the value for the button, and to grey out the button.

I finally tried this:

$(document).ready(function(){
  $('form').submit(function(){
    this.submit();
    $("input[type=submit]").prop("disabled", true);
    return false;
  });
});

However, it seems to be like the first example in that the submit button value is not transmitted with the form, despite that the this.submit() apparently should be happening before the disabling.

I've also tried just hiding the button, but that causes the page to get re-arranged, and the poor user will accidentally hit something completely different on the mouse bounce, rather than hitting the submit twice.

I could replace the button with something of the same size, or try to copy the submit value into a hidden input element with the name, but that is getting grotesque. Is there a simple way to meet this simple need?

jjanes
  • 37,812
  • 5
  • 27
  • 34
  • The only way I was able to do this with .net (which caused the same issues because the submit of the page included some slow async code) was to cover over the button with an image that showed a disabled button. You should be able to find examples of this under .net tagged questions. – Hogan Mar 19 '14 at 14:46

6 Answers6

6

Instead of binding the submit event of FORM, try using the click handler of submit button and used:

$('form :submit').click( function () {
    $(this).prop("disabled", true).closest('form').append($('<input/>', {
        type: 'hidden',
        name: this.name,
        value: this.value
    })).submit();
});
A. Wolff
  • 74,033
  • 9
  • 94
  • 155
  • This looks like the winner. I guess making a new hidden element was not as grotesque as I thought. The only problem with it is that on firefox the button remains disabled if the person uses the back button to get back to the form again. But the original 3 methods I tried all have that problem also. – jjanes Mar 19 '14 at 19:52
  • Except, this does not work if there is a form action actually named 'submit', which the legacy code does have some of. So between these two features, it looks like there is no transparent way to do this. – jjanes Mar 25 '14 at 19:34
  • @jjanes What do you mean with "form action actually named 'submit'"? Submit handler? – A. Wolff Mar 25 '14 at 19:43
  • @A-Wolff I have some legacy forms that named their submit button "submit", i.e. ``. I think I'll just bite the bullet and modify them. – jjanes Mar 25 '14 at 19:52
  • @jjanes ya because using as attribute name 'submit' for an input inside of a FORM overwrite native DOM method `submit()` of this FORM. – A. Wolff Mar 25 '14 at 20:04
1

How about this?

$('form').submit(function(e){
     e.preventDefault();
     this.submit();
     $("input[type=submit]").prop("disabled", true);
});
Dean Whitehouse
  • 884
  • 1
  • 8
  • 25
0

How about faking a disabled button-look through a CSS class, along with your 2nd piece of code?

$(document).ready(function(){

  $('form').submit(function(){
    $("input[type=submit]").addClass("disabled");

    $(this).submit(function() {
      return false;
    });

    return true;
  });

});
Praxis Ashelin
  • 5,137
  • 2
  • 20
  • 46
0

I tried multiple options for this but it didn't work properly. My solution is pretty simple. Just tie the form submit function with the parent element. In my case, it is like this:

$('.page-content').on('submit', '#frmOnlineOrder', function(e)
{
    e.stopImmediatePropagation();
    e.preventDefault();
    //put your working code here
}

You are welcome to try this solution. Please do let me know if this is helpful.

SushilB
  • 13
  • 1
  • 10
0

I also had some HTML5 field validation (required) that I needed to run on submit and submitting the form via jQuery ($('form').submit()) would bypass the validation.

This solution is working for me though, note that I also have 2 submit buttons and I give each of them a different value to discern which 'action' was clicked:

$('form :submit').click(function(e) {
    // if any fields fail html5 validation, proceed normally in order to display errors
    if(!$('form')[0].checkValidity()) {
        return;
    }

    // add class to demark that button has been clicked
        if(!$(this).hasClass('disabled')) {
            e.preventDefault();
            e.stopPropagation();
            $(this).addClass('disabled');
            $(this).click();
            $(this).prop("disabled", true);
        }
});

<button type="submit" name="action" value="submit" class="btn btn-primary">Submit</button>

<button type="submit" name="action" value="save" class="btn btn-primary">Save Draft</button>
jose mera
  • 11
  • 2
-2

I always though this would work great. Also stupid enough.. I have had .attr work and not .prop

.attr('disabled', 'disabled');
xlordt
  • 521
  • 4
  • 15