Disable button on form submission but post button value

Here is (yet another) answer to the question of how to deal with preventing the user from clicking on the form submission button more than once. This solution makes it appear that the button has been disabled.

Under the covers, it creates a disabled button to display to the user, and hides the actual button so that its value is posted. I also move the hidden button so that the extra element doesn't mess up CSS selectors.

Also note the check for invalid form fields. If you omit this check, and form validation fails, then the user winds up with a form that wasn't posted (because client-side validation failed) but the buttons are disabled.

// Disables buttons when form is submitted
$('form').submit(function () {
    // Bail out if the form contains validation errors
    if ($.validator && !$(this).valid()) return;

    var form = $(this);
    $(this).find('input[type="submit"], button[type="submit"]').each(function (index) {
        // Create a disabled clone of the submit button
        $(this).clone(false).removeAttr('id').prop('disabled', true).insertBefore($(this));

        // Hide the actual submit button and move it to the beginning of the form
        $(this).hide();
        form.prepend($(this));
    });
});

Because you can submit a form other ways than simply clicking the submit button it's better to add a listener to the form's submit event rather than the click event on the submit button. This jQuery event listener should work on any form and prevent it from being submitted more than once.

$('form').on('submit', function(e) {
    if (!$(this).data('submitted')) {
        $(this).data('submitted', true);
    }
    else {
        e.preventDefault();
    }
});

To make the form look disabled you could add some css that makes the form look disabled and then add the classname on form submission.

$('form').on('submit', function(e) {
    if (!$(this).data('submitted')) {
        $(this).data('submitted', true).addClass('disabled');
    }
    else {
        e.preventDefault();
    }
});