Prevent Users from Submitting a Form TwiceBy Scott Mitchell
When a user clicks a submit button in a form, their browser makes a request back to the web server for the specified URL. On the web server, the user's input is processed and some action is taken based on the input. A database record might be added, an email might be sent, and so on. One potential issue that can arise is if a user submits a form, but there is a delay in getting back a response from the server. A user may think that the button click didn't "take", so they click it again. This can lead to two form submissions, resulting in two database records being added, two emails being sent, or whatever.
A recent Quick Tip at ASP101.com caught my eye the other day.
The tip, titled Stop Users from Double Clicking, showed how
The tip is remarkably simple - in the button's client-side
onclick event, simply set the button's
In my projects, I've always used a somewhat different method that is a little more involved. Rather than just disabling the submit button, I "freeze" the screen and show a message explaining that their data is being processed. Personally, I prefer the look and feel of the frozen screen, as it's more obvious that the data has been sent back to the server and is being processed. Also, it prevents the user from clicking other submit buttons that may be on the page. Read on to learn more about both of these techniques!
Disabling a Button When Clicked
onclick event handler:
onclick event handler calls the
DisableButton(button) function, passing in a reference
to the button (
DisableButton(button), the button's
is set to
true and its
value (the displayed button text) to "Submitted". To see this technique in
action, check out this live demo.
|Disabled Buttons and Data Sent on Form Submission|
WARNING: Browsers do not send the data on form submission for those controls
information that the button was clicked in the form submission. The result is that, if using ASP.NET, the corresponding Button
Web control's |
"Freezing" the Page On Form Submission
One technique I've seen in commercial Web applications (such as FogBugz) to prevent double form submissions involves "freezing" the screen when the form is submitted. Specifically, the screen is frozen by placing a full screen, absolutely positioned element above all other elements on the page (specifically a
<div> element). This covers up
the content beneath the element and prevents the user from interacting with the form elements.
To start, we need to define some cascading stylesheet (CSS) classes that define the appearance of the frozen screen. There are three CSS clases:
FreezePaneOff- "hides" the
<div>so that the page is interactive (i.e., not frozen)
FreezePaneOn- the frozen screen element is actually a full screen
<div>with an inner
<div>that displays a message (like "Processing Your Request"). This CSS class defines the settings for the outer
InnerFreezePane- specifies the style settings for the inner
<div>, which shows a message to the user (like "Processing Your Request").
classattribute from the default (
FreezePaneOff) to the CSS classes corresponding to the frozen frame (
Let's start with the CSS classes:
Note that the
FreezePaneOff CSS class indicates a hidden element (
visibility: hidden; display: none;).
FreezePaneOn CSS class, however, shows the element and positions it at the top of the page giving it a full
width and height. The
z-index value specifies the "layer" of the element on the page. The 999 value is used so
that it appears above other elements on the page. The
-moz-opacity:0.85 make the background pane translucent for Internet Explorer and Mozilla FireFox, respectively.
InnerFreezePane CSS class defines the syle settings for the inner message.
In addition to the CSS classes, we need to add the
<div> elements to the page. Initially, the outer
class attribute should be set to
FreezePaneOff. When the form is submitted,
is positioned at the top of the page) and updates the outer
<div>'s CSS class. Additionally, we need
onclick event, for example).
Note that the
FreezeScreen(msg) function accepts as input the message to display in the inner
<div>. To see this script in action, check out the
There are some shortcomings as well as loose ends that could be tied up with the frozen screen approach. For one thing,
the screen really isn't frozen. The user can still scroll, still click HTML elements not covered by the outer
can still hit the Back button, refresh the page, and so on. Also, I've not thoroughly tested this approach across a wide spectrum of browsers.
It works on IE 6, FireFox 1.5, and Opera 9.0 (although the opacity setting doesn't work), but I'm uncertain to its support
in older browsers. However, despite these potential shortcomings, this technique has worked well for me in my projects,
and hopefully you can get some use out of it, too!