views:

1799

answers:

9

sometimes when the response is slow,

one might click multiple times on the submit button.

How to prevent this from happening?

+1  A: 
<form onsubmit="if(submitted) return false; submitted = true; return true">
chaos
+3  A: 

Disable the submit button soon after a click. Make sure you handle validations properly. Also keep an intermediate page for all processing or DB operations and then redirect to next page. THis makes sure that Refreshing the second page does not do another processing.

Shoban
A: 

Hash the current time, make it a hidden input on the form. On the server side, check the hash of each form submission; if you've already received that hash then you've got a repeat submission.

edit: relying on javascript is not a good idea, so you all can keep upvoting those ideas but some users won't have it enabled. The correct answer is to not trust user input on the server side.

llimllib
Dont this look "Too much"? ;-)
Shoban
That sounds like it would just keep a user from submitting the form more than once per second. If I submit the form at 2009-05-29 12:13:37, then the server won't let me submit another form with that same hash, but if I clicked Submit at 2009-05-29 12:13:38, it would go through.Also, your technique would prevent 2 different users from simultaneously submitting two different forms: one of them would be kicked out, even though it would be possibly the first submission from him.
Sarah Vessels
@moneypenny your first objection is false, the hash would be of the time the form was sent to the user, not the time they submit. If you're truly worried about the second, you have plenty of options. Add their session ID to the string you hash, and/or check all fields of the form for exact sameness; two users probably didn't submit exactly the same form.
llimllib
@Shoban I'm sorry, I don't follow what you're saying
llimllib
I suppose you could use micro-time. Seems dirty though.
Aiden Bell
how does it "seem dirty"? It seems like a simple, elegant solution to me.
llimllib
This would require you to store a table of hashed forms somewhere or to add a column to whatever table you're presumably inserting to for the hash. This solution seems excessive to me.
epalla
"Excessive" is in the eye of the beholder. If you *really* need to prevent duplicate form submissions, at least part of the solution has to be server-side. "You can't trust users."
Ben Blank
A: 

You could also display a progress bar or a spinner to indicate that the form is processing.

Tony Borf
A: 

Using JQuery you can do:

$('input:submit').click( function() { this.disabled = true } );

&

   $('input:submit').keypress( function(e) {
     if (e.which == 13) {
        this.disabled = true 
     } 
    }
   );
Boris Guéry
What if the form is submitted by pressing ENTER in a textbox after the button is disabled?
ichiban
Disabling the button like this will prevent the user to press ENTER then.But, right it needs to bind a keypress on the submit input
Boris Guéry
+3  A: 

Here's simple way to do that:

<form onsubmit="return checkBeforeSubmit()">
  some input:<input type="text">
  <input type="submit" value="submit" />
</form>

<script type="text/javascript">
  var wasSubmitted = false;    
    function checkBeforeSubmit(){
      if(!wasSubmitted) {
        wasSubmitted = true;
        return wasSubmitted;
      }
      return false;
    }    
</script>
ichiban
+2  A: 

Use unobtrusive javascript to disable the submit event on the form after it has already been submitted. Here is an example using jQuery.

EDIT: Fixed issue with submitting a form without clicking the submit button. Thanks, ichiban.

$("form").submit(function() {
    $(this).submit(function() {
        return false;
    });
    return true;
});
What if the form is submitted by pressing enter in a textbox?
ichiban
+2  A: 

Client side form submission control can be achieved quite elegantly by having the onsubmit handler hide the submit button and replace it with a loading animation. That way the user gets immediate visual feedback in the same spot where his action (the click) happened. At the same time you prevent the form from being submitted another time.

If you submit the form via XHR keep in mind that you also have to handle submission errors, for example a timeout. You would have to display the submit button again because the user needs to resubmit the form.

On another note, llimllib brings up a very valid point. All form validation must happen server side. This includes multiple submission checks. Never trust the client! This is not only a case if javascript is disabled. You must keep in mind that all client side code can be modified. It is somewhat difficult to imagine but the html/javascript talking to your server is not necessarily the html/javascript you have written.

As llimllib suggests, generate the form with an identifier that is unique for that form and put it in a hidden input field. Store that identifier. When receiving form data only process it when the identifier matches. (Also linking the identifier to the users session and match that, as well, for extra security.) After the data processing delete the identifier.

Of course, once in a while, you'd need to clean up the identifiers for which never any form data was submitted. But most probably your website already employs some sort of "garbage collection" mechanism.

Rob
A: 

I know you tagged your question with 'javascript' but here's a solution that do not depends on javascript at all:

It's a webapp pattern named PRG, and here's a good article that describes it

Pablo Fernandez