The title says it all: I want to prevent clients from posting the exact same data twice (or more) but I also want to use client-side validation. Let’s first explain why this is problematic.

 

Preventing duplicate form submits is easy. You disable the submit button in the onclick event handler:

<input type="submit"
       onclick="$(this).attr('disabled', 'disabled');" />

This works fine without client-side validation. But now suppose that some client-side validation rule has triggered and the form is invalid. You now have a disabled submit button on your form.

 

To fix this, we must make sure to only disable the button when the form is valid. We introduce a Javascript function to do this:

function disableSubmitButton(b) {
  // Disable submit button as soon as possible to prevent
  // duplicate submits.
  $(b).attr('disabled', 'disabled');
  var valid = $(b.form).valid();
  if (!valid) {
    // Re-enable submit button when form is invalid.
    $(b).removeAttr('disabled');
  }
}

And our button now looks like this:

<input type="submit"
       onclick="disableSubmitButton(this);" />

The valid() method is available from the jQuery Validation Plugin. It provides a lot of client-side validation options and can be used out-of-the-box with ASP.NET MVC3.

 

That was easy. When a user clicks the button, it is disabled immediately unless the form is invalid. However, this appears to work only in Internet Explorer. In Chrome and Safari (I haven’t tested Firefox), if the form is valid, it is no longer submitted. This has probably something to do with the fact that I define a custom onclick handler, preventing some default onclick handler from running. In Internet Explorer this problem doesn’t occur for some reason.

 

To fix this, I changed the disableSubmitButton function to the following:

function disableSubmitButton(b) {
  // Disable submit button as soon as possible to prevent
  // duplicate submits.
  $(b).attr('disabled', 'disabled');
  var valid = $(b.form).valid();
  if (valid) {
    // Submit form when it is valid.
    $(b.form).submit();
  }
  else {
    // Re-enable submit button when form is invalid.
    $(b).removeAttr('disabled');
  }
  // Always return false to prevent Internet Explorer from
  // posting the form (which would then be the second post).
  return false;
}

The submit button is changed to:

<input type="submit"
       onclick="return disableSubmitButton(this);" />

A bit more work than I thought it should be but it works.

Ronald Wildenberg

Author Ronald Wildenberg

Coming from an Artificial Intelligence background, turned developer after graduating. Interested in the tiny programming language details that make your life simpler but also in high-level designs that solve business problems in the most efficient way. And everything in between of course.

More posts by Ronald Wildenberg
8 May 2011

Leave a Reply