Disabling the Postback Button
page 1 of 1
Published: 01 May 2006
Unedited - Community Contributed
Abstract
The ASP.NET rutime will not recognize a postback initiated by a disabled button. In this article, Craig demonstrates a generic and reliable way to disable a button after a user-click and still allow the server to recognize the postback.
by Craig Shoemaker
Feedback
Average Rating: 
Views (Total / Last 10 Days): 15623/ 21

Introduction

Have you ever been asked to create an ASP.NET page that required you to protect users from themselves?  All too often, this need is seen when a page initiates a server side process that takes a significant amount of time to complete.  Often, users will fill out a mortgage application form or perhaps an e-menu for a favorite pizza place, but in the time it takes the server to respond, the user clicks on the submit button several times which can result in too many loans and too much pizza.

Protecting users from themselves is an application usability issue and there are many different ways you may choose to approach the problem.  One way to prevent users from posting the same request more than once is to disable the button that initiates the request to the server.  Disabling the submit button will keep users from replicating data or creating parallel requests for an identical action.

Unfortunately, there is a problem.  In ASP.NET, you cannot simply disable the button before you initiate the postback.  Once a control is disabled on the client, the ASP.NET runtime no longer recognizes the control in the form collection.  So how do you stop the submit button from being clicked multiple times and keep the control exposed to the page code-behind?

The Process

The solution is quite simple. The first step is to run a custom JavaScript function that executes before the ASP.NET __doPostBack function.  This function will initiate a command to disable the button, but it will only do so after a short delay.  Immediately after this command, processing will continue to contact the server and complete the postback.  The key to this technique is that the wait time is long enough for the server to get the information it needs, but a short enough not to confuse the user with unexpected changes to the user interface.

The Code

The following example builds a basic ASP.NET page that includes a single button on the page.  When you click on the button, the page will postback to the server, but before the request is made a JavaScript function will run.  The function will wait a fraction of a second and then disable the button.  This fulfills the criteria of waiting long enough to contact the server, but disables the button fast enough that it is not distracting to the user.

HTML

Starting with a new, blank ASP.NET WebForm, add a single button control to the page:

Listing 1: ASP.NET markup for the Save button

<asp:button id="btnSave" text="Save"runat="server" />

Code Behind

On the server, you must add to the attributes of the server control to hook into the client-side click event.  When the user clicks on the button, the custom JavaScript executes before the ASP.NET __doPostBack function.  The addition to the control is all done in the page load event and is only necessary upon the first request of the page.

Listing 2: Add a client-side OnClick event to an ASP.NET button

Private Sub Page_Load(ByVal sender As System.Object,_
        ByVal e As System.EventArgs) HandlesMyBase.Load
 
  If Not Me.Page.IsPostBack Then
   Me.btnSave.Attributes.Add("onclick",_"btnSave_Click(this);")
  End If
End Sub

In a real-world scenario when the user clicks on the button, the page will make the appropriate calls to a business layer in order to perform some kind of task (apply for a loan, order pizza, etc.).    For the sake of this example, the page will send a command to the server to tell it to hesitate for five seconds by calling the Sleep method of the current Thread.  This will simulate a long server process.  The following code will demonstrate this technique in action.

Listing 3: Add a five second delay to simulate real-world performance issues

Private Sub btnSave_Click(ByVal sender As _
        System.ObjectByVal e As System.EventArgs)_
        Handles btnSave.Click
  System.Threading.Thread.Sleep(5000)
End Sub

JavaScript

The JavaScript for this solution is built to be generic and reusable.  In order to achieve the desired effect, the browser must wait before disabling the button, but not hinder the server from processing.

The flow of execution for this process:

1. Run the custom function when the user clicks the button.

2. Initiate a delay on the client which will eventually disable the calling button.

3. Return control to ASP.NET which will contact the server for the postback.

Add the following JavaScript in the <head> section of your page.  The following is the implementation of this logic.

Listing 4: Generic JavaScript functions that disables a control after a short interval

<script type="text/javascript">
function DisableControl(controlId)
{
  document.getElementById(controlId).disabled =true;
}
 
function DisableControl_SetTimeout(controlId,interval)
{
  setTimeout("DisableControl('" +controlId + "')",interval);
}
 
function btnSave_Click(control)
{
  DisableControl_SetTimeout(control.id,100);
}
</script>

The DisableControl function contains a reference to the calling control’s ID as its only argument.  When the function executes then the control is located on the page, its state is updated and it becomes disabled.

JavaScript’s built-in setTimeout function executes a function after waiting a specified amount of time.  The DisableControl_Timeout function calls DisableControl using the setTimeout feature.

The btnSave_Click function will run when the user clicks on the button.  Since you wired up this function in your code-behind passing by this as an argument, you may access the control’s properties directly.

You might be wondering why you would not just pass a reference to the control to each of the functions, rather than the control ID.  The JavaScript setTimeout function requires that you pass in a string of the function name and arguments along with delay interval.  If you pass in an object reference as an argument, the page will encounter a JavaScript error.

Run this page in your browser to test its behavior.

Conclusion

When communicating with a web server, some processes may take a significant amount of time to complete.  During the processing time, developers often want to protect themselves from impatient users who may continue clicking the "submit" button in a futile attempt to speed up the process.  A popular way of dealing with this problem is to disable the control that initiates the post to the server.

The ASP.NET runtime does not recognize a button that is disabled before postback is sent to the server; therefore, if you want to disable the button that originates the postback, you must "wire up" some custom behavior that will produce the same result.  This article demonstrated how to send the request to the server and then disable the button after a short interval.  This technique works because the control is disabled after the server is contacted and before the user observes any inconsistencies in the appearance of the page.



User Comments

Title: fgfg   
Name: nfn
Date: 2013-01-22 7:59:28 AM
Comment:
vnc
Title: sdasdas   
Name: dqwe
Date: 2012-07-21 9:48:18 PM
Comment:
wqeqw
Title: dff   
Name: fffff
Date: 2012-05-22 3:11:16 PM
Comment:
fdfsdf
Title: web developer   
Name: Hussam
Date: 2010-12-17 6:05:38 AM
Comment:
thank you so much
Title: developer   
Name: andrea
Date: 2010-08-31 6:19:50 AM
Comment:
Thanks, I have just a question, there could be some issues in this approach?
e.g.
I set the time amount to 100.
Could happen that for some reason the button disable fires before postback ?
Maybe it's a stupid question, thanks anyway.
Title: developer   
Name: Gari
Date: 2010-04-12 12:23:41 AM
Comment:
Thank u
I was really looking for this only
Title: Developer   
Name: Ken
Date: 2010-02-11 4:01:16 PM
Comment:
Thanks a lot. Very useful
Title: Awesome   
Name: Julie Sucher
Date: 2009-11-11 5:41:24 PM
Comment:
Far superior to the GetPostBackEventReference approach
Title: Thanks   
Name: Dave
Date: 2009-09-03 6:01:57 PM
Comment:
Not sure why this was so difficult for me. But this walk through made it a lot more clear. Thank you much.
Title: GREAT   
Name: ANKITH
Date: 2009-01-20 7:22:45 AM
Comment:
THANK U.......
Title: great   
Name: sachin sonone
Date: 2008-11-28 3:13:20 AM
Comment:
good
Title: Great Article   
Name: Ray Akkanson
Date: 2008-09-04 10:00:08 AM
Comment:
It was really helpful.

Ray Akkanson
Title: Not working with latest Firefox (August, 2008)   
Name: Douglas
Date: 2008-08-26 4:41:38 PM
Comment:
This works nicely with IE, but with Firefox the button simply does nothing once it's clicked, and there is no postback. Anybody else experience this? If so, is there a workaround for Firefox?
Title: Great Article   
Name: Ray Akkanson
Date: 2008-07-30 11:52:03 AM
Comment:
Great article. I would also like know about utilizing __doPostBack method in case we need create user controls on the fly.

Ray Akkanson
Title: Thank you for the info   
Name: Neil Ajero (Phil)
Date: 2008-06-17 9:48:22 PM
Comment:
Thanks a lot! This was a great help...

Thanks again.
Title: Simple and Effective   
Name: Paulo Mondragon (México)
Date: 2008-04-10 6:37:04 PM
Comment:
Thanks a lot. Just what I need, a simple and functional example.
Title: Thanks   
Name: Mr. Patel
Date: 2008-04-09 3:40:49 PM
Comment:
Thank you so much, this is exactly what i was looking for. I wouldn't have been able to figure this one out...

Thanks.
Title: Thanks so much   
Name: cacooma
Date: 2008-02-20 12:47:19 PM
Comment:
This saved me alot of time. Thanks so much!
Title: Thank You!   
Name: Tony Courter
Date: 2008-02-06 5:11:47 PM
Comment:
Awesome. exactly what I was looking for. Muchas Gracias
Title: Validation   
Name: Duncan Ford
Date: 2007-05-11 3:02:29 PM
Comment:
This is great if you don't have any page validators on your page. You don't want to disable the button if validators are fired, and there is no easy way to test the validators from javascript.
Title: Great Help   
Name: Saurabh dixit
Date: 2007-04-10 9:52:39 AM
Comment:
It is greate help, i was really looking for some help on this, even tried AJAX update panel. but not able to get is......Thanks man
Title: It did NOT work with Validation   
Name: Ali Gholami
Date: 2006-12-17 9:47:14 AM
Comment:
It did NOT work with Validation!
Title: Disabling the Postback Button   
Name: Srini
Date: 2006-11-13 5:33:36 PM
Comment:
Great help.

Thanks.
Title: good   
Name: 虚拟主机
Date: 2006-06-22 9:47:57 PM
Comment:
a nice site,very good.
Title: Disabling the Postback Button   
Name: Craig Shoemaker
Date: 2006-05-30 3:40:42 PM
Comment:
Raj:

You can change the interval time by adjusting the interval argument passed in to the JavaScript setTimeout method.

In the above code you can change the value "100" to some other value to change the delay amout. This value is in milliseconds.

function btnSave_Click(control)
{
DisableControl_SetTimeout(control.id,100); <-- interval value
}

This technique should be independent of RAM as the timeout is measured in milliseconds and the JavaScript runtime should be able to keep the timing consistent among machines.

Craig Shoemaker
Polymorphic Podcast
http://polymorphicpodcast.com/
Title: Time to set   
Name: Raj
Date: 2006-05-30 1:39:01 PM
Comment:
Hi,
Nice article. But how can we determine the interval to be used ?

Does it change with the configuration of the system i.e. RAM of the client machine, memory of the client etc. ??
Title: AD   
Name: ANIRUDH
Date: 2006-05-27 4:46:47 AM
Comment:
FINE IT HELPED ME A LOT
Title: Disabling the Postback Button   
Name: Andrew Mooney
Date: 2006-05-23 10:17:50 AM
Comment:
I hope MS adds this feature in then ext the release of ASP.NET. I couldn't get Firoz Ansari's solution to work with ASP.NET 2.0. But, yours work perfectly. Thanks!!!
Title: Preventing multiple clicks   
Name: Firoz Ansari
Date: 2006-05-07 6:32:56 AM
Comment:
If you want to raise any server side event from disable button then you just need to explicitly call __doPostBack from button through GetPostBackEventReference method of Page object. This is best solution for handling this kind of issue.
http://www.firoz.name/2006/05/07/how-to-preventing-multiple-clicks/

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-05-05 12:58:01 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search