Animated example of the button disabling technique in this article.The overzealous double-clickers amongst our users often make it desirable to temporarily disable the controls that trigger server side processing. Previously, I’ve shown you how to disable a button during a postback, how to disable a button during a partial postback, and even written a server control to automate the latter.

However, what if you wanted to be more thorough and disable all of the buttons on a page?

In this post, I’m going to show you how to do just that. I’ll also show you how to disable only the buttons in the UpdatePanel raising the event. Finally, for the jQuery users out there, I’ll show you how to simplify the process down to one line of code.

Building a demonstration page

To demonstrate this technique, we’re going to need a page with several buttons that generate partial postbacks. An expanded version of the typical Hello World AJAX sample (a la DateTime.Now) will get the job done:

Using getElementsByTagName to find the buttons

You’re probably familiar with the JavaScript function getElementById and our handy $get shortcut for it, but how about GetElementsByTagName?

This useful JavaScript function returns an array of elements matching a specified HTML tag name. For example, document.getElementsByTagName(‘div’) would return an array of every <div> on the page.

Since we know that ASP.NET Button controls render as <input type=”submit”> elements, the solution is clear. We can use a BeginRequest and EndRequest handler to put that to work during a partial postback:

Limiting the technique to a single UpdatePanel’s Buttons

A nice feature of getElementsByTagName is that it can be used to search the children of most any element. So, if you’d like to limit this functionality to a particular region of a page, that’s easy too.

An UpdatePanel renders its ContentTemplate as a <div> element. With that in mind, the trick here is to call getElementsByTagName on the <div>’s children instead of on the entire document. To do so, only a few changes to the code are needed:

As you can see, it’s basically the same code. It takes a slight bit more work to find which UpdatePanel raised the partial postback, but it’s identical after that.

You can use this same method to target the children of any control that renders as an HTML element. This includes Accordion panels, Wizard steps, TabPanel containers, and many others. If you’re unsure how a particular control renders, using FireBug to inspect your page can dramatically accelerate the discovery process.

jQuery could become your new best friend

If you haven’t tried using jQuery with ASP.NET AJAX before, I highly recommend it. To give you an idea of why, here’s how you could use jQuery to re-write the first example:

That’s all there is to it. Really.

The UpdatePanel targeted functionality can also be accomplished with similarly concise jQuery code:

It’s hard not to love that!

Conclusion: We’ve only just begun

In your own implementation, you might want to limit the technique to only a certain, focal UpdatePanel (or other container) instead of any that raises a postback. You might also want to add a few UI improvements, such as changing button text, blurring the buttons, or changing the mouse cursor during the partial postback.

All of this is possible, with only slight modifications to the sample code. In fact, the download below includes the blurring (it makes a noticeable difference in FireFox).

Additionally, keep in mind that this code contains no error handling. I’m assuming that there are buttons on the page, buttons in every UpdatePanel, and that a button inside an UpdatePanel raises every event.

In production, you should definitely be more careful than I have been here. At very least, check that the array is actually an array before trying to iterate over it.

Source download

Finally, here is the source code download for the full demonstration page, including the client script for the second example:

Download Source: (4kb)

Shameless plug

If you like the idea of having this functionality, but don’t like the idea of having to implement it, then keep an eye out for the next version of PostBack Ritalin. I’ll be integrating this into it as an optional feature in the next release.