Disabling a User Interface Element During a Partial Page Postback
By Scott Mitchell
Introduction
When using Microsoft's ASP.NET AJAX framework and an UpdatePanel whose
ChildrenAsTriggers
is set to True (the default), anytime a user interface element
within the UpdatePanel would normally cause a full page postback, a partial page postback is performed instead. For example, clicking a Button Web control
or selecting a different item from a DropDownList control whose AutoPostBack
property is set to True normally causes a full page postback, but
if these controls are within an UpdatePanel, a partial page postback occurs instead. But what happens if a partial page postback is taking a while to complete
and the user triggers the partial page postback again? Or what if during this lull she clicks some other Button in the same UpdatePanel, thereby causing a
second partial page postback to ensue?
If a partial page postback is made from the same UpdatePanel while a partial page postback is ongoing, the first partial page postback is aborted and the second postback commences. Aborting a partial page postback simply means that the ASP.NET AJAX framework on the browser no long listens for a response back from the server for that request. It does not stop processing on the server, or rollback any state changes that may have occurred on the server. Consequently, if on a partial page postback you are inserting records into a database or making some other state change, if a user clicks a Button in an UpdatePanel to instigate a partial page postback, but then clicks the same Button again while the partial page postback is still ongoing, there will be two duplicate records inserted in the database.
There are a couple of ways to prevent the user from resubmitting a partial page postback while it's still ongoing. The most effective way, in my opinion,
is to "freeze" the frame by overlaying the screen with a <div>
element. (See the final demo in the article,
Providing Visual Feedback with the UpdateProgress Control.) Another option is
to disable the user interface element that triggered the postback during the partial page postback lifecycle. This prevents the user from resubmitting
the partial page postback. Read on to learn more!
The Need for Disabling the User Interface During a Partial Page Postback
The download available at the end of this article includes a demo named
NoDisabling.aspx
that illustrates the default behavior. The demo
consists of an UpdatePanel control containing two Button Web controls. On the first page load, a Session variable named NumberOfClicks
is set to 0:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
|
In the Buttons' Click
event handlers this Session variable is incremented and the Button that was clicked along with the value of the
Session variable are displayed in the Results
Label control. What's more, both Click event handlers sleep for five seconds to add an artifical
delay in the partial page postback. This delay is present to mimic the time it might take to perform the partial page postback in a real-world setting.
The Click
event handler for Button1
follows:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
|
A recent article of mine, Performing Client Actions in Response to Partial Page Postbacks,
showed how to execute client script at various stages during the partial page postback's lifecycle. If you haven't yet read this article, please do so before
continuing here. In the article I showed how to build a client-side event logger that displays a message as each client-side event of the
PageRequestManager
object is raised. The demo available for download includes such functionality.
To see the need for disabling the user interface during a partial page postback, visit the demo page through a browser. Click the first button to instigate a partial page postback. The event log dislays two entries:
initializeRequest
beginRequest
endRequest
, is not displayed until the response is returned from the server (or if the partial page postback is aborted).
During the partial page postback, click the first button again. This starts the second partial page postback. In the first stage of the second partial
page postback (initializeRequest
), the first partial page postback is aborted. This behavior is evidenced by the event log in the screen shot
below. Note that the first two events, initializeRequest
and beginRequest
, occurred at 11:08:14, and were triggered by clicking
"Button 1" for the first time. Two seconds later, I clicked "Button 1" again. This triggered the third event log entry, initializeRequest
, at
11:08:16. Because the first postback is still outstanding, it is automatically aborted. The fourth event log entry, endRequest
, indicates the
conclusion of the first partial page postback. And the fifth event log entry (beginRequest
) signals the second stage of the second partial
page postback.

What's important to understand is that aborting a postback causes the client API to stop listening for a response, but it does not stop processing on the server
or rollback any state changes. This is made clear by the output displayed in the Results
Label at the conclusion of the second partial page
postback. Even though the first partial page postback was aborted, the Session variable has been incremented twice.

In cases where the partial page postback performs some sort of state modification it is prudent to prevent the user from re-triggering the partial page postback when the partial page postback is ongoing. This article examines one approach for accomplishing this functionality: by disabling the user interface element that caused the partial page postback.
Determining the User Interface Element that Triggered the Partial Page Postback and Disabling It
As we've already seen, whenever a partial page postback commences, the
PageRequestManager
raises a series of client-side events. The first one is
initializeRequest
. Following that, the
beginRequest
event is raised. The beginRequest
is
passed an args
object that includes information on what user interface element caused the partial page postback. Specifically, this information
can be retrieved via args.get_postBackElement()
. Once we have a reference to the user interface element that caused the postback, we can
disable it by setting its disabled
property to true
:
function PageRequestManager_beginRequest(sender, args)
|
This code disables the user interface element at the start of the partial page postback (before the actual HTTP request is transmitted from the client to the server). However, this code alone is not sufficient - we need to enable the user interface element once the partial page postback completes.
Re-Enabling the User Interface Element that Triggered the Partial Page Postback
The
PageRequestManager
raises its endRequest
event at the
conclusion of a partial page postback, regardless of whether the partial page postback completed successfully, ended from an error, or was canceled or
aborted from client-side script or by user action. Therefore, it makes sense to re-enable the user interface element in the endRequest
event
handler.
Unfortunately, the endRequest
event handler is not passed a reference to the control that triggered the partial page postback.
Therefore, we need to save this information in a page-level variable. The following JavaScript illustrates how to accomplish this. Note the page-level
variable, uiId
. This variable is assigned the id
attribute of the element that caused the partial page postback in the
beginRequest
event handler. It is then used in the endRequest
event handler to get a reference to the element and set its
disabled
property to false
.
|
Note that in the endRequest
event handler I use the $get(id)
function to get a programmatic reference to the element specified by the ID value uiId
. $get(id)
is a function that
is part of the ASP.NET AJAX framework's client API. It serves as a shortcut to the Sys.UI.DomElement
class's getElementById
function.
Testing the Disabled UI Functionality
The download available at the end of this article includes a demo named
Disabling.aspx
that has the same user interface as NoDisabling.aspx
,
but implements the client-side disabling/enabling logic we just discussed. The following screen shot shows the page shortly after "Button 1" has been clicked.
Note that "Button 1" is disabled - it does not respond to clicks until it is re-enabled.

After the partial page postback completes, "Button 1" is re-enabled and can be clicked again to perform another partial page postback.

Stopping Other Partial Page Postbacks
Disabling the user interface element that triggers the partial page postback ensures that the same control won't initiate another postback, thereby aborting its ongoing request. But what if another element in the same UpdatePanel triggers a partial page postback? For example, what happens if, in the
Disabling.aspx
demo, the user clicks "Button 1" and then, during the postback, clicks "Button 2"? Clicking "Button 2" aborts the "Button 1"
postback and then initiates the "Button 2" partial page postback logic.
To prevent this we can either disable the entire user interface in the event of a partial page postback (instead of just "Button 1"). See the final demo in the Providing Visual Feedback with the UpdateProgress Control article for such an example. Another option is to programmatically prevent a partial page postback from starting if there is an ongoing one.
The sender
object passed into the initializeRequest
event handler has a function named get_isInAsyncPostBack()
that returns a Boolean value indiciating if there is an ongoing partial page postback. To permit only one partial page postback at a time, check this
function and cancel the current request if it returns true
. The following JavaScript snippet illustrates how to accomplish this:
function PageRequestManager_initializeRequest(sender, args)
|
In addition to canceling the requested partial page postback, the above code also displays an alert explaining to the user that their current request cannot be processed until the ongoing request finishes. The following screen shot shows this functionality in action. "Button 1" has been clicked and is in the midst of a partial page postback. Because of the script we added in the previous section, the button is disabled. If the user clicks "Button 2" during the partial page postback, an alert box is shown and the partial page postback request from "Button 2" is canceled.

Conclusion
In some circumstances, a partial page postback performs some action on the server that affects the state of the web application. For such partial page postbacks it's usually important that the user does not repeatedly cause the same partial page postback. For example, if the partial page postback inserts a record into the database, triggering the same partial page postback multiple times - by, say, clicking a Button repeatedly - may result in duplicate database entries. To remedy this you can either disable the entire user interface by means of an overlaid
<div>
element or you can more
selectively disable the user interface element that triggered the partial page postback for the duration of the postback. This article examined the
latter approach.
Happy Programming!
Further Readings:
Attachments: