Check out JobNimbus - CRM for Contractors and Service Professionals.
Disable Button on Submit (Prevent multiple submits)
When a user clicks a button on a web page that submits the page (or does an AJAX asynchronous submit), depending on the load on the server and latency, the user may have to wait upwards of many seconds in order for the process to complete. During the time, a user may think something has not worked and may attempt to click the button again, even multiple times. If you are doing complex operations, it could cancel these actions and start over. Worse yet, if you are inserting items in a database, it could cause duplicate entries or other concurrency issues.
Here is a way to set up an ASP.NET button to be disabled when it is clicked and re-enable itself after the postback operations complete. I will show an example using a standard ASP.NET postback and the newer AJAX-based asynchronous post back that only causes a partial page update.
NOTE: This has been tested in IE7, IE6, Firefox 2, and Safari 3.
First, add the following javascript to your page:
<script language="javascript" type="text/javascript">
// disables the button specified and sets its style to a disabled "look". function disableButtonOnClick(oButton, sButtonText, sCssClass) { // set button to disabled so you can't click on it. oButton.disabled = true; // change the text of the button.oButton.value = sButtonText;
// IE uses className for the css property. oButton.setAttribute('className', sCssClass); // Firefox, Safari use class for the css property. (doesn't hurt to do both). oButton.setAttribute('class', sCssClass);}
</script>
There are a couple of things to note in the javascript. The button is set to disabled state. The value of the button text is changed to make it even more obvious that the button was clicked and is processing. We have to set both the "className" and "class" attributes so this will work in IE, Safari, and Firefox correctly.
Next, add the following CSS style property:
<style type="text/css">
/* Some browsers don't make it obvious that a button is disabled so set this css class
to make the button obvious that it is grayed out and disabled. */
.disabled_button
{color:#aca899;
background-color:#efefef;
border:solid 1px #c0c0c0;
}
</style>
This CSS is optional but some browsers don't make it obvious that a button is disabled even when you set the disabled property so I like to change the CSS property to make it more noticeable. Also, if you are using a custom style on your buttons, you will definitely need this because setting to disabled will not change your custom CSS properties to a "grayed-out" state.
We will add a button that posts normally, and we will add a button that is wrapped in an ASP.NET AJAX UpdatePanel so that it causes a partial page postback. Add the following HTML to your page:
<!-- This does a full page postback and sets the textbox to the current date/time. -->Date of Submit: <asp:TextBox ID="txtDateSubmit" runat="server"></asp:TextBox>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" />
<br />
<br />
<br />
<!-- Wrapping in an UpdatePanel causes this section to do a partial page postback.This sets the textbox to the current date/time without posting back the entire page. --><asp:UpdatePanel ID="UpdatePanelSubmitAsync" runat="server">
<ContentTemplate>
Date of Submit (Asynchronous): <asp:TextBox ID="txtDateSubmitAsync" runat="server"></asp:TextBox>
<asp:Button ID="btnSubmitAsync" runat="server" Text="Submit Async" onclick="btnSubmitAsync_Click" />
</ContentTemplate>
</asp:UpdatePanel>
Now add the following C# code to the page's code behind:
protected void Page_Load(object sender, EventArgs e)
{ // set up button client click event. // PostBackOptions allows us to get the ASP.NET postback options for the control specified. PostBackOptions optionsSubmit = new PostBackOptions(btnSubmit); // set the OnClientClick to call our disableButtonOnClick javascript function. We do this in the // code behind instead of the HTML design view because we may want to localize this string and // we need to get a reference to the post back event for this button. // The reason we need a reference to the postback event is because when you set a button's css // style property to disabled, it automatically cancels the submit action so we need to make sure // the button still runs it's submit action after we disable the button. btnSubmit.OnClientClick = "disableButtonOnClick(this, 'Please wait...', 'disabled_button'); ";btnSubmit.OnClientClick += ClientScript.GetPostBackEventReference(optionsSubmit);
// do the same for the asynchronous postback button. PostBackOptions optionsSubmitAsync = new PostBackOptions(btnSubmitAsync); btnSubmitAsync.OnClientClick = "disableButtonOnClick(this, 'Please wait...', 'disabled_button'); ";btnSubmitAsync.OnClientClick += ClientScript.GetPostBackEventReference(optionsSubmitAsync);
}
protected void btnSubmit_Click(object sender, EventArgs e)
{ // simulate load on the web server for 2 seconds.System.Threading.Thread.Sleep(2000);
// set textbox to the current date/time so we can verify things are working correctly.txtDateSubmit.Text = DateTime.Now.ToString();
}
protected void btnSubmitAsync_Click(object sender, EventArgs e)
{ // simulate load on the web server for 2 seconds.System.Threading.Thread.Sleep(2000);
// set textbox to the current date/time so we can verify things are working correctly.txtDateSubmitAsync.Text = DateTime.Now.ToString();
}
We put the OnClientClick event setup in the Page_Load() event so that it is re-set up each time the page is submitted. Also, this allows us to get access to the GetPostBackEventReference() method which gives us a dynamic way of getting the control's submit behaviour. When you set an HTML submit button to disabled, it automatically cancels the submit action so we have to call the ASP.NET PostBack event manually in order to make the post occur.
Now run the page. When you click the buttons, they should be disabled (not clickable) until the threading sleep ends and the page returns the resp
Popular Articles
Last viewed:
- C# Download File with Progress Bar
- Global.asax Events in IIS 6 and IIS 7 for Static Resources
- How to Highlight the Day in the ASP.NET Calendar Control with the SelectedDate Property
- Fixing Relative Paths in C# ASP.NET When Using Url Rewriting
- C# Store/Retrieve File in Database Image Field using ODBC
- ASP.NET CSS Highlight TextBox on Focus
Recent comments
- thank you for sharing
1 day 1 hour ago - Great explanation and more questions
2 days 5 hours ago - Insertion of illegal Element:
4 weeks 4 days ago - Insertion of illegal Element: 32
4 weeks 4 days ago - re "But, this will NOT work."
5 weeks 5 days ago - Unable to cast COM object of t
5 weeks 5 days ago - Saved my life
5 weeks 6 days ago - nice
8 weeks 5 days ago - good article
9 weeks 6 days ago - windows 2008 server backups
11 weeks 5 days ago

Java script validation for Same button submit not working
it is a nice article but i have problem javascript date validation when i submit the button it validating but when i click the javascript popup ok it is post backing and insering record Db even wrong Valid Date.
Can u some one help me pls asap.
Don't forget to set usesubmitbehaviour to false!
UseSubmitBehavior="false" on the button will append some code to the onclick javascript that is rendered to force it to use the __dopostback .net javascript event.
A similar, but easier, solution
Hey, I came up with a similar solution. Let me know what you think: http://thecodebug.com/?p=33
Preventing of the multiple clicking of Submit button
It can be done this way:
function btnSubmitClicked(t) {
<%=Page.GetPostBackEventReference(btnSubmit as Control)%>;
t.disabled = true;
}
...
Preventing of the multiple clicking of Submit button
Problem:
To prevent multiple submits.
Note.
After Submit button is clicked the client side code and server side code is executed in following sequence:
a) Client side event OnClientClick (and javascript function calling), and then OnClick event which performs Post Back.
b) Server side method Page_Load(...), and then method btnSubmit_Click(...).
It is normally.
If javascript function sets btnSubmit.disabled=true; then the event handler btnSubmit_Click(...) on the server side is not being evoked. The reason is: disabled button cannot be clicked.
Solution.
Change the sequence of performing operations on the client side:
At first do postback when button is not disabled.
And then disable the button. Button will remain disabled till page is rerendered.
It can be done this way:
...
OnClientClick = "btnSubmitClicked(this)"
Text= ...
...
suppose validation on the page.
suppose i am checking validation for server side and client side. is this working or not
thanks
thanks you it works
Not working
Hi,
This is nice article.
as i have written another javascript function for the same button for validationg the input fields, and also written this method to disable the button. in this case, the javascript which is written for validations is not working.
Can you please help me in this regard
Thanks
Ravikrishna
Great!
Thank you so much, it really helped
Maybe this can help
protected override void Render(HtmlTextWriter writer)
{
ClientScript.RegisterOnSubmitStatement(typeof(string), "DisableButton", "buttonToDisable.disabled = true;");
base.Render(writer);
}
Saludos.
Aha! Problems with UpdatePanel? Sorted ...
I've had problems with this technique when the page also contains an UpdatePanel (.NET 2.0. Don't ask).
In my case the submit button is outside of the UpdatePanel; the UpdatePanel exists only because it contains a dropdown that must change the controls available on the page via an async postback.
The problem I was having was that Page_ClientValidate() was breaking the UpdatePanel; that is to say the next change of the dropdown after the submit button was pressed with invalid entries on the page resulted in no async postback by the UpdatePanel. The second dropdown change did work. Very odd.
I used Reflector to look at WebUIValidation.js in System.Web.dll and found that it modifies a variable called Page_BlockSubmit. This variable appears to, er, block submissions! Good name that, really ...
So, in my version of this JavaScript, if Page_ClientValidate() returns false then I set Page_BlockSubmit to false and then return false (which stops submission anyway).
The UpdatePanel now works. Validation failures stop page submission. The button is disabled when the page is valid and a postback occurs.
Job done. But not quickly ...!
Really Very nice article need this type of implementation.
Very Nice article. Wasted so many times. Your article has given very gr8 energy to me.
BUTTON ASP.NET XML asp:Button
BUTTON ASP.NET XML
asp:Button ID="btnFinish" Text="Finish" OnClick="btnFinish_Click" OnClientClick="window.setTimeout('disableFinishButton()',0); return true" runat="server"
JAVASCRIPT
script type="text/javascript"
function disableFinishButton()
{
var arrInputs = document.getElementsByTagName('INPUT')
for (var i = 0; i < arrInputs.length; i++)
{
if (arrInputs[i].getAttribute('id') != null)
{
if (arrInputs[i].getAttribute('id').indexOf('btnFinish') > -1)
{
arrInputs[i].disabled = true
break
}
}
}
}
script
Works for me with only a few lines of code
Contact Details
I am genuinely interested in you proving my method wrong.
Hope you don't :)
For contact details
go to On Schedule
The settings page allows one
The settings page allows one to choose between two "disabling methods" 70-649 exam.
The default method, "Use a flag variable...", works in all browsers 70-291 exam.
The other method, using HTML's "disabled" attribute, for some mysterious reason don't work in my Internet Explorer. I can't debug it, because I'm running IE under Wine 640-863 exam and it's cumbersome, so just don't choose this disabling method 350-030 exam. I leave it there for some developer who runs Windows and wants to fix it.
Not working with FireFox
If you use this code:
protected void btnSubmitAsync_Click(object sender, EventArgs e){
//beep .. this is my modification
System.Media.SystemSounds.Beep.Play();
// simulate load on the web server for 2 seconds.
System.Threading.Thread.Sleep(2000);
// set textbox to the current date/time so we can verify things are working correctly.
txtDateSubmitAsync.Text = DateTime.Now.ToString();
}
When you make double clik to btnSubmitAsync button, you can hear, that FireFox post it twice.
Any idea? I have FireFox version .0.11. In IE works good.
Thank you...
Great article....Thanks...
Now working with ValidationGroups
Right, I've now got this working with ValidationGroups by passing the group name to the Page_ClientValidate() method like this: Page_ClientValidate('validationgroup')
If like me you are registering the client script server side using ClientScript.RegisterClientScriptBlock(), you will need to register a separate script for each validation group. This caught me out at first as I use a helper routine, calling it for each button that I wanted the "click once" functionality applied to. This helper registers the client script, but because the "key" parameter was the same each time, only the first one got registered (with whatever ValidationGroup happened to be on that button). I got around this by including the ValidationGroup name in the RegisterClientScriptBlock() "key" parameter, ensuring that a separate client script is registered for each validation group. My complete helper routine is as follows:-
public static void ForceSingleButtonClick(Page page, Button button)
{
const string StyleName = "disabled_button";
string scriptKey = "clickoncebtn" + button.ValidationGroup;
if (!page.ClientScript.IsClientScriptBlockRegistered(scriptKey))
{
// Register script (use both IE and FF class attribute names).
StringBuilder sb = new StringBuilder();
sb.Append(" function disableButtonOnClick(oButton)");
sb.Append(" {");
sb.Append(" if (typeof(Page_ClientValidate) == 'function') ");
sb.AppendFormat(" if (Page_ClientValidate('{0}') == false) return false; ", button.ValidationGroup);
sb.Append(" oButton.disabled = true; ");
sb.AppendFormat(" oButton.setAttribute('className', '{0}'); ", StyleName);
sb.AppendFormat(" oButton.setAttribute('class', '{0}');", StyleName);
sb.Append("}");
// Register a separate script for each validation group.
page.ClientScript.RegisterClientScriptBlock(
typeof(WebUtility),
scriptKey,
sb.ToString(),
true);
}
// Alter button click to call javascript before normal postback.
button.UseSubmitBehavior = false;
PostBackOptions options = new PostBackOptions(button);
button.OnClientClick =
"disableButtonOnClick(this); " +
page.ClientScript.GetPostBackEventReference(options) + "; return;";
}
Hope this helps someone! I would be interested to hear of any problems etc.
Andy (andrew.stephens@cheshire.gov.uk)
Another problem...
Sorry, I should have said that I was referring to my first comment regarding firing of validators, rather than the author's original code above.
Andy
Another problem...
I've just found that this won't work when controls have their ValidationGroup property set. The button will fire all validators regardless of whether they are in the same ValidationGroup or not. As yet I haven't found a fix. Anyone have any ideas?!
Andy
Validation Controls
Thanks Andy. I didn't even notice the issue. Glad you found it before I implemented this into production. Funny that you posted on the very day I found this great article.
Problems with this...
This does not work when there are validator controls on the page. To fix this, add the following lines to the start of the javascript function (before the line 'oButton.disabled = true;'):
if (typeof(Page_ClientValidate) == 'function')
if (Page_ClientValidate() == false)
return false;
Also, I have found intermittent problems with the button's server-side click event handler firing twice (it seems to happen on our production server where the postback round-trip takes longer than on my dev PC). To fix this, add a "return" to the end of the button's OnClientClick property:
btnSubmit.OnClientClick = "disableButtonOnClick(this, 'Please wait...', 'disabled_button'); ";
btnSubmit.OnClientClick += ClientScript.GetPostBackEventReference(optionsSubmit);
btnSubmit.OnclientClick += "; return;";
Hope this helps someone
Andy
Awesome thanks, fixes IE9
Thanks for this following up post. I had this working from IE7 (or 8), but noticed when I upgraded to IE9 it started failing with "Microsoft JScript runtime error: Sys.ParameterCountException: Parameter count mismatch.". The IE 8 to 9 backwards compatbility breakage was obvious when using the "run in backwards compatbility mode" button. So by applying this change, specifically the "btnSubmit.OnclientClick += "; return;";" text combined with the other reply post about setting the useSubmitBehavior property to false, fixed my error above. So now it runs in IE9 without backwards compability mode. WooHoo! Thanks a bunch!
John
John i have an answer!!!!
Hi John. I had the same problem and re-installing Java first and them IE helped me. Firs delete both of them and then Java goes first! Good luck
do my essay for me
Helped a lot
if (typeof(Page_ClientValidate) == 'function')
if (Page_ClientValidate() == false)
return false;
This solved my problem. Thanks a lot
disable button on submit
nice article, thanks!
Why not do it this way?
asp:Button ID="btnFinish" Text="Finish" OnClick="btnFinish_Click" OnClientClick="window.setTimeout('disableFinishButton()',0); return true" runat="server"
script type="text/javascript"
function disableFinishButton()
{
var arrInputs = document.getElementsByTagName('INPUT')
for (var i = 0; i < arrInputs.length; i++)
{
if (arrInputs[i].getAttribute('id') != null)
{
if (arrInputs[i].getAttribute('id').indexOf('btnFinish') > -1)
{
arrInputs[i].disabled = true
break
}
}
}
}
/script
Thanks!
Worked Like a Charm!
I have changed as I require.
Modified to
asp:Button ID="btnFinish" Text="Finish" OnClick="btnFinish_Click" OnClientClick="window.setTimeout('disableFinishButton()',0); return true" runat="server"
function disableFinishButton()
{
var arrInputs = document.getElementsByTagName('<%= btnSubmit.ClientID%>')
arrInputs.disabled = true
}
Best Regards,
Damodar
Nice Article
Thank you Very much. this script made easy to my task
Why not do it this way?