Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC - How to prevent double click submit with jquery.validate.unobtrusive lib?

I need to avoid the double click submitting behavior. I'm using the client validation with the unobtrusive library. I have the following code for avoiding the double clic:

jQuery.fn.preventDoubleSubmit = function () {
         var alreadySubmitted = false;
         return jQuery(this).submit(function () {

             if (alreadySubmitted)
                 return false;
             else {
                 alreadySubmitted = true;
             }
         });
     };

     jQuery('form').preventDoubleSubmit();

Unfortunately, if my form has some validable fields (for example, a required field), the code above is still being fired, hence, even if I correct any mistakes on the form, I won't be able to submit it again.

How can I fire the double click code after the validation has been succesfully done?

like image 440
Rodrigo Caballero Avatar asked Dec 27 '10 14:12

Rodrigo Caballero


People also ask

How is unobtrusive validation implemented in ASP net MVC?

Unobtrusive Validation allows us to take the already-existing validation attributes and use them client-side to make our user experience that much nicer. The Unobtrusive script files are included automatically with new MVC projects in Visual Studio, but if you don't have them you can get them from NuGet.

How does jQuery unobtrusive validation work?

Unobtrusive Validation means without writing a lot of validation code, you can perform simple client-side validation by adding the suitable attributes and including the suitable script files. data-val-required=”This is required.”

How to disable client-side validation in ASP net Core?

Disable client-side validation AddViewOptions(options => { options. HtmlHelperOptions. ClientValidationEnabled = false; });


6 Answers

You can also use the JQuery One event.

I have found that I could get past most guards against double-clicks by double-clicking fast. Using the one event is the only true way to make sure the event is only fired once. I don't think this technique will work "out of the box" with an input type=submit tag. Instead, you can simply use an input type=button or JQueryUI's .button().

$("#submitButton").one("click", function(event) {
   $('#theForm').submit();
});

If you need to re-wire the event on a validation error (or other circumstance), I recommend that you create a function for the event handler. The function isn't necessary in this example because all the event handler does is submit the form, but in more complicated scenarios you may want to avoid repeating yourself.

function submitClick(event) {
   $('#theForm').submit();
}

$("#submitButton").one('click', function(event) {
   submitClick(event);
});

// This handler will re-wire the event when the form is invalid.
$('#theForm').submit(function(event) {
   if (!$(this).valid()) {
      event.preventDefault();
      $('#submitButton').one('click', function(event) { submitClick(event); });
   }
});

You could obviously add the disabling code here if you wanted to give feedback to the user that the button doesn't work anymore. One great side-effect of using the One event is that you don't actually have to make the button disabled, you can use a style of your own.

function submitClick(event) {
   $('#submitButton').addClass('disabledButton');
   $('#theForm').submit();
}

$("#submitButton").one('click', function(event) {
   submitClick(event);
});

// This handler will re-wire the event when the form is invalid.
$('#theForm').submit(function(event) {
   if (!$(this).valid()) {
      event.preventDefault();
      $('#submitButton').one('click', function(event) { submitClick(event); });
      $('#submitButton').removeClass('disabledButton');
   }
});

JQuery One Event: http://api.jquery.com/one/

like image 147
Ryan P Avatar answered Sep 19 '22 15:09

Ryan P


I solved it with the following code:

var tryNumber = 0;
 jQuery('input[type=submit]').click(function (event) {
     var self = $(this);

     if (self.closest('form').valid()) {
         if (tryNumber > 0) {
             tryNumber++;
             alert('Your form has been already submited. wait please');
             return false;
         }
         else {
             tryNumber++;
         }
     };
 });

NOTE: You can also replace the:

return false;

line, for:

self.attr('disabled', true);

BUT, if you use the name of your submit buttons on your controller for extra logic, they will be sent as null. (you can use an additional hidden field to charge them before submitting)

that's it, hope it helps

Rodrigo

EDIT: Thanks to these posts: jquery newbie: combine validate with hidding submit button

like image 42
Rodrigo Caballero Avatar answered Sep 17 '22 15:09

Rodrigo Caballero


Why not just use:

function disableButtons() {
    var form = $(this);
    var btns = $("input:submit", form);

    if (!form.valid()) {
        // allow user to correct validation errors and re-submit
        btns.removeAttr("disabled");
    } else {
        btns.attr("disabled", "disabled");
    }
}

to disable your buttons and activate it using:

$("form").bind("submit", disableButtons);
like image 33
Space Monkey Avatar answered Sep 16 '22 15:09

Space Monkey


Based on Ryan P's popular answer I created the following generic solution that also works with my ajax form.

decorate your custom submit button with the following class:

<button type="button" class="one-click-submit-button">Submit</button>

Add the following to your javascript file:

function OneClickSubmitButton() {
    $('.one-click-submit-button').each(function () {
        var $theButton = $(this);
        var $theForm = $theButton.closest('form');

        //hide the button and submit the form
        function tieButtonToForm() {
            $theButton.one('click', function () {
                $theButton.hide();
                $theForm.submit();
            });
        }

        tieButtonToForm();

        // This handler will re-wire the event when the form is invalid.
        $theForm.submit(function (event) {
            if (!$(this).valid()) {
                $theButton.show();
                event.preventDefault();
                tieButtonToForm();
            }
        });
    });
}

OneClickSubmitButton();

since this is an ajax form we want to reload the handlers if we fail server validation.

function MyForm_OnSuccess() {
    if (true if your form passed validation logic) {
        //do something since your form submitted successfully
    } else { //validation failed on server
        OneClickSubmitButton(); //reinitialize the button logic
    }
}

Obviously if you don't have ajax forms you can omit the whole OneClickSubmitButton function business and run $('.one-click-submit-button').each(... directly.

like image 40
Alex Avatar answered Sep 18 '22 15:09

Alex


I have a form that uses MVC3 unobtrusive validation, and a viewmodel with a [RemoteAttribute]. It looks to me like the form's submit event only fires after all validation has passed. I'm currently using this, and it seems to work:

<input type="submit" value="Submit the Form" 
    data-app-disable-on-submit="true" />

$('form').live('submit', function() {
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]')
                .attr('disabled', 'disabled');
})

;

I set breakpoints on both the remote attribute validation action method and the HttpPost action method. Clicking the submit button the first time hits the breakpoint on the validation action method. At this point, the button is still enabled. I can click it multiple times, and after resuming the validation method, the HttpPost is hit only once. When the HttpPost is hit, the submit button is disabled.

Update

Right you are Alex. So an updated version of the above would look like this:

$('form').on('submit', function() {
    $(this).find('input[type="submit"][data-app-disable-on-submit="true"]')
                .attr('disabled', 'disabled');
})
like image 37
danludwig Avatar answered Sep 16 '22 15:09

danludwig


 $('form').submit(function () {
 $('input[type="submit"]', this).attr('disabled', 'disabled');
   });
like image 24
kavitha Reddy Avatar answered Sep 16 '22 15:09

kavitha Reddy