Prevent double click on form submission

Recently I've been going over the Hub logs and fixing issues which have caused exceptions to be raised in the application.

One in particular had me stumped for a while. An exception was being raised in an attempt to unregister a server from the Hub, but the server did not exist in the database - in theory this is impossible and should never happen.

The only explanation I could come up with, was that the form was being submitted multiple times. I tested my theory by double clicking the submit button, and lo-and-behold, the exception was raised.

So now I knew the cause, but how to solve it?

One option is to handle the situation on the server side, but that would add lots of ugly and complex error checking code all over the application.

The second option is to handle it on the client side, by disabling the submit button after it's clicked, then submitting the form. It turns out this is rather simple to do by leveraging the onclick event.

<input value="Unregister" type="submit" onclick="this.disabled=true,this.form.submit();"/>

The Hub currently has about 50 forms, and updating each one manually would be rather tedious and error prone, so I batched it:

$ find ./ -type f | xargs sed -i "s|type=[\"\']submit[\"\']|type=\"submit\" onclick=\"this.disabled=true,this.form.submit();\"|"

GOTCHA: If you already have onclick or JS bindings, this could cause unexpected behavior.

You can get future posts delivered by email or good old-fashioned RSS.
TurnKey also has a presence on Google+, Twitter and Facebook.


Guest's picture

if you do that, the user can't retry when the network on client-side has problem (cable, wireless disconnect...)
Alon Swartz's picture

and the solution I proposed could easily be extended to handle network issues, but I'd still argue that implementing the logic on the client side trumps that on the server side.

ShawnMilo's picture

If you append a setTimeout() which sets 'this' to enabled again in n seconds (where n is more than enough to deal with double-clicks and "not sure if I really clicked it" re-clicks), that might be good enough for most cases.



Post new comment