A friend of mine called me today asking how exactly do we disable buttons on all our websites while clients post data to the server. He says that most of tips that he found on Internet are either prevent buttons from posting back or look quite complicated. He was wondering if our solution is different.
I don't know if the code that we use is
that different from most of the sites out there (I kinda doubt that because of my belief in evolution) but I thought it would be nice to post it in this blog just in case.
Most of our forms are implemented on the client side. Buttons submit their data using the good old
xmlHttpRequest object (ah, pardon - Asynchronous JavaScript), namely its implementation in wonderful
MS library. But my friend asked about the server side. So, server side it is.
There is not that much of a code. Therefore, I will show it first and then explain it in details.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CodeEffects.Rule.Harness
{
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.DisableButtonOnPostBack(this.btnGo, "Wait...");
}
public void DisableButtonOnPostBack(Button button, string text)
{
button.Attributes["onclick"] =
string.Format(
"this.value = '{0}';this.disabled = true;{1};",
text,
button.Page.ClientScript.GetPostBackEventReference(button, null));
}
}
}
Create a new page and add a button to it or use the existing page/button. I'll save some space here and won't bother you with HTML of that page. For the same reason I won't create any event handlers for the button. ID of that button is "btnGo".
The page's load handler calls the method DisableButtonOnPostBack, passing it the reference to our button and text that we want the button to display during the post back. Notice that you must call this method on each page request, whether it's a post back or not.
The method DisableButtonOnPostBack simply appends a new "onclick" attribute to the button. The client will use this attribute to execute a small JavaScript code it contains. The code does three small things:
- It assigns a new value to the button. As you know, the Text property of the System.Web.UI.WebControls.Button class represents button's "value" attribute on the client. So, the button will display that value during the post back. The keyword "this" in the context of a button represents the button itself. So, the phrase "this.value = 'Wait...'" for the client means a command "take the button btnGo and display it with text 'Wait...'".
- It also disables the button during the post back. The phrase "this.disabled = true;" does just that. Shocking, I know :)
- And finally, it adds the client code that submits the form to the server. The best way to do this in ASP.NET is to use Page's ClientScript property (which is an instance of the ASP.NET ClientScriptManager) to call it's GetPostBackEventReference method. This method returns the line of JavaScript that calls for form submission. Again, this is the easiest way to submit the form from the ASP.NET markup. So, we just append the returned line to our button's "onclick" handler and we are done.
That's it. Very compact and elegant. Run it, test it. Of course, you would want to make the DisableButtonOnPostBack static and move it to your own framework that handles things
your way. But this is too obvious to discuss here, right?
Hope this small info helps someone out there :)