Disable a button control during postback.
ASP.NET, UI By Dave Ward on April 17th, 2007Postback Ritalin has been getting a lot of search hits intended to find a button disable technique for full .NET postbacks. So, this example is for all of you searching for a non-AJAX solution.
The trick is to use the OnClientClick and UseSubmitBehavior properties of the button control. There are other methods, involving code on the server side to add attributes, but I think the simplicity of doing it this way is much more attractive:
<asp:Button runat="server" ID="BtnSubmit" OnClientClick="this.disabled = true; this.value = 'Submitting...';" UseSubmitBehavior="false" OnClick="BtnSubmit_Click" Text="Submit Me!" />
OnClientClick allows you to add client side OnClick script. In this case, the JavaScript will disable the button element and change its text value to a progress message. When the postback completes, the newly rendered page will revert the button back its initial state without any additional work.
The one pitfall that comes with disabling a submit button on the client side is that it will cancel the browser’s submit, and thus the postback. Setting the UseSubmitBehavior property to false tells .NET to inject the necessary client script to fire the postback anyway, instead of relying on the browser’s form submission behavior. In this case, the code it injects would be:
__doPostBack('BtnSubmit','')
This is added to the end of our OnClientClick code, giving us this rendered HTML:
<input type="button" name="BtnSubmit" onclick="this.disabled = true; this.value = 'Submitting...';__doPostBack('BtnSubmit','')" value="Submit Me!" id="BtnSubmit" />
This gives a nice button disable effect and processing text, while the postback completes.
If you found this but are more interested in an AJAX solution to disable buttons during partial postbacks, check out either Postback Ritalin or CSS style as AJAX progress indicator.
Possibly related posts
What do you think? Your comments are welcome.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this comment" link underneath the comment you're replying to.
2 Mentions Elsewhere
- deviceZero » Disable a button control during postback.
- Disable button onclientclick twice ASP.Net « Yasserzaid’s Weblog


What in case of an image button. how to disable it and still the post back will occur
I believe you can use the same method. ImageButton doesn’t support UseSubmitBehavior, but shouldn’t be needed since it’s not a true form submit element.
I tried as per your code sample piece here in VS.Net 2003 and used on a asp:button control. the page does postback but the event is not firing for that button.. how to handle that..??
I don’t think ASP.NET 1.1 supports UseSubmitBehavior.
What you could probably do is use Attributes.Add() in your code behind to add the same client script to the button control.
thanks for your reply sir. but i tried using attributes.add() in some ways i know like written a javascript function to “disabled=true” code block. but if so, as per the above explanations, the c# event handler is not firing.
what else to do or what to add in attributes.add() function. Please help me out sir?
Try something like this:
Thank you Dave Ward. I have been trying for 2 days to figure out the image button and your solution was the one I needed!!! Works great.
Works perfectly, I’ve been looking for a very simple solution for some time now. Great post, keep up the good work.
thank you so much i had tried hell lot of things to get this but i din knew it was so simple
thank you so much
Finally! Thank you so much!
I’m new to ASP.net. How can I apply here?
Currently, the button fires when hitting the refresh button in IE. I want to fire the button only when clicked and not on refresh the page or F5.
I’m not sure if this is related to the topic.
Many thanks!
edcon
The reason that’s happening is because the button click causes a POST to the server. When you refresh a page that’s the result of a POST request, the browser re-POSTs that request, which results in the server seeing the button being clicked again.
That’s a tough problem to reliably avoid.
One way is to make the submit button redirect to a “please wait” type page while the process completes, but that introduces other complexities.
Another way to handle it is to set a Session variable when the process begins and not accept another submission for a certain timeframe.
Hope that helps.
Hi Dave,
Thank you for giving me some options to consider. But when I tried to redirect (response.redirect) to the same that solves the issue but I’m not sure if this the right way to do it. I got the idea from this link, http://forums.asp.net/t/1151989.aspx
Do you think this will lead to another problems?
Edcon
I think that’s a good way to handle it. That’s what I was referring to in my first suggestion.
Thanks! It helped me a lot.
-edcon
Thank you for the post, this helps a lot. But, I’m having one problem. I’m using this button to run a report and the report opens in an Adobe window. Once the report opens in another window, when I go back to the main page where the button was, the button is still disabled until I click to refresh the page. Is there any way to get the page to refresh or the button to become enabled again before the Adobe window opens? Thanks!
Hey. Thx for the post. I get a javascript error in my browser (IE7) when doing this. It does not seem to be a problem with the javascript code itself, because I took all the code out of the function to see. Any ideas?
Never mind me…..blonde moment!! Your stuff works great!!
It is not working with field validations, disables the button even when there are invalid fields.
Shakeel.
I am having the same problem. Form validation is showing errors on the form and stops the page from submitting but now the button will not allow me to click on it after I correct the information on the form. Is there any way to check to see if the form is valid?
I don’t know of a way to do that using this declarative method. You’d probably need to write a client side event handler to handle a later event that only fires when the page is valid.
How do you do this with a asp menu instead of a button?
I’m not sure. I don’t use the Menu control. I believe those render as <A> tags though, so you’d need to go about it completely differently than this.
I’d suggest posting on the asp.net forums.
Once again, great solution!!!
Very interesting stuff- thanks for posting. Just one question (which I probably should know): where is the $get() js function defined? I’m not familiar with it.
Thanks, Frank
It’s part of the ASP.NET AJAX client side framework. In the usual one-parameter case, it’s functionally identical to document.getElementById. Just a shortcut.
Any know how to get this working in conjunction with an Ajax ConfirmButtonExtender? Cos, UseSubmitBehavior=”False” breaks the extender.
This method isn’t suitable for an AJAX scenario. It’s only intended for full postbacks.
Hi,
It worked for me. Thank you very much.
I am scratching my head from last 2 hours.
Thank you Dave! This will serve as a great stop-gap until I implement some proper server mechanism for preventing multiple submits.
If you have an image button or anything else for that matter, you can inject the postback manually by using the GetPostBackEventReference of the control
protected override void Render(HtmlTextWriter writer)
{
string postback = ClientScript.GetPostBackEventReference(btnSubmit, string.Empty) + ” ; return false;”;
btnSubmit.OnClientClick = “javascript:” + btnSubmit.ClientID + “.disabled=true;” + postback;
base.Render(writer);
}
It works!
..thanks
THANK YOU SOOOOOO MUCH!!!!!!!!!!
I have been struggling with an AJAX solution for days. I’m new to this, so simple things take me much longer than they should, so this simple approach was EXACTLY what I was looking for.
THANKS!
Superb! Thanks very much
To incorporate validation into the above approach, you can add this to the end of the click logic:
Note: The initial disabling is still useful in that it prevents a race condition (user vs validation).
Excellent post my friend, i came across this situation few moments ago, i tried different solutions but nothing until i saw your post.
best regards
marquito
This solution disables event firing.
Better way to use onclick disabling:
theForm.onsubmit=function()
{
if (currentSubmitControl)
currentSubmitControl.onclick=function()
{ return false; };
}
var currentSubmitControl=null;
var currentSubmitEvt=null;
document.onclick=function(eventObject)
{
var evtTarget=null;
if (eventObject==null)
evtTarget=window.event.srcElement;
else
{
if (eventObject.srcElement!=null)
evtTarget=eventObject.srcElement;
if (eventObject.target!=null)
evtTarget=eventObject.target;
}
if (evtTarget)
{
currentSubmitControl=evtTarget;
currentSubmitEvt=currentSubmitControl.onclick;
}
};
post back ritalin is usefule for me ..but suppose i have 3 buttons named “process”,”reset”,”Cancel”
when i click on process the text of this is changing to wait.. which i have specicified thru postbackritalin which is fine ,at the same time is there any way to change the “reset” and “cancel” to wait states restricting the user not to do any operation…
This was extremely helpful and just what I was looking to accomplish. Thanks for sharing this solution with us.
This is really helpful. I am too much of a n00b to get it to work for me, though. I have a different kind of button, that shows text at distinct time points. You click the button once and then it displays a sentence, then it pauses, then it displays a different sentence. I don’t want the client to be able to see the sentences more than once, so I am trying to disable the button w/o preventing the sentences from being shown. All my attempts disable the button completely so the client never sees anything. This is the basic code w/o anything to disable. Where can I put the right function or line of code to disable the button while still allowing the text to display one time? THANKS for any help.
function timedText() { var t1=setTimeout(“document.getElementById(‘txt’).value=’Chinese Sentence’”,0); var t2=setTimeout(“document.getElementById(‘txt’).value=’XXXXXXX’”,3000); }
wait–the second part of that code is a form:
thanks! this is the best and easiest solution i have found.
Removed the OnClick=”BtnSubmit_Click” and it worked for me. Thanks!
i am creating link button dynamically, which calls few COM operations. How can i prevent user to click multiple times on the link button?
With LinkButtons, there’s no client-side “disabled” property like with regular Button contracts. What you can do is replace this in the example above:
With this:
And it will effectively disable the link after it is clicked once.
thanks MR.Dave Ward
its Work
From
Muhammad Noman Shahid
Pakistan
Thanks. Your solution worked perfectly. Just out of curiosity, is there a way to do the same thing while also displaying a label on top of the page saying “Processing…”?
You can use something like jQuery’s BlockUI to do that. See this post for some details: http://encosia.com/2008/10/04/using-jquery-to-enhance-aspnet-ajax-progress-indication/
YOU JUST SAVED ME 1 DAY OF FRUSTRATION WITH THIS…. can’t believe this little property was the root of my problem!!!
Here is a code sample that shows how to the submit button on submission of the form without breaking the client-side validation of .net: http://www.mgitsolutions.com/blog/2009/10/27/how-to-disable-button-on-form-submit-in-net/
Nice, Clean, Simple!
Brilliant, thanks for sharing such an easy solution to a common problem!
Works like a charm, was looking for this for a long time. Such a simple solution. :)
Use a javascript function like the following if you want to disable the button AND still have working client validation, call the function from the OnClientClick attribute:
function CheckSubmit() {
cmdSave = document.getElementById(‘cmdSave’);
cmdSave.disabled = true;
originalText = cmdSave.value;
cmdSave.value = “Saving Changes…”;
Page_ClientValidate();
if (!Page_BlockSubmit) {
cmdSave.value = originalText;
cmdSave.disabled = false;
}
}