Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Performing Client Actions in Response to Partial Page PostbacksBy Scott Mitchell
The previous three articles in this series focused on building AJAX-enabled web applications using server-side techniques and controls. For instance, Using the UpdatePanel examined how to define regions on the page that participate and are updated by partial page postbacks; Providing Visual Feedback with the UpdateProgress Control showed how to use the UpdateProgress control to display feedback during a long-running partial page postback.
The ASP.NET AJAX Framework also includes a rich client-side library and event model that enables page developers to create and execute client script
and event handlers that integrate with the ASP.NET AJAX Framework. This article starts our examination of client-side development with the ASP.NET AJAX
Framework. In particular, it examines the client-side
PageRequestManager object, which includes methods and events tied to the partial page
postback mechanism. In a nutshell, we can use the
PageRequestManager object to execute client-side script immediately before or after a partial
This article discusses the basics of the client-side
PageRequestManager object and includes examples that show how to abort and cancel partial page postbacks
as well as how to scroll to a particular location on screen after a partial page postback completes. These working demos are available for download at the end of
this article. Read on to learn more!
The Client-Side Events of a Partial Page Postback
As discussed in Using the UpdatePanel, whenever a Web control within an UpdatePanel causes a postback - such as a Button Web control being clicked - instead of a regular postback the UpdatePanel performs a partial page postback. A partial page postback asynchronously communicates with the web server and sends the page's form field values. On the server, the page is re-rendered but only the HTML content for the appropriate UpdatePanel regions are returned to the browser. These regions are then dynamically updated. All of this hard work is handled for us by the client- and server-side pieces of the ASP.NET AJAX Framework.
Our jobs as page developers are simple: just add an UpdatePanel control to the page and all that magical AJAXy goodness happens automatically. But what happens if we need more control over the partial postback life-cycle? For example, imagine that we need to execute some client-side script after the partial page postback completes? Or what if we want to cancel the partial page postback if some condition is true? The good news is that such custom functionality is available. We can create client-side event handlers that execute in response to certain events during the life-cycle of a partial page postback.
The partial page postback is managed on the client-side by the
Whenever a partial page postback is initiated, the
PageRequestManager object performs the following client-side actions:
initializeRequestevent is raised - this is the first event raised during the partial postback life-cycle and affords us an opportunity to determine the HTML element that triggered the postback and cancel the postback, if needed.
beginRequestevent is raised - this event is raised just before the request is sent to the server. The UpdateProgress control uses this event to displayed it's output.
- The request is sent to the server and the page is re-rendered there.
pageLoadingevent is raised when the server returns its response.
pageLoadedevent is raised. This event is raised whenever the content on the page is refreshed, be it via a full page postback or a partial page postback.
endRequestevent is raised, signalling completion of the partial page postback lifecycle.
"Viewing" the Events Raised During the Partial Page Postback Life-cycle
To better understand the stages of the partial page postback life-cycle, I've created a very demo with a Button in an UpdatePanel. When this Button is clicked, a partial page postback begins. I've also added client-side script that displays a message on screen as each of these events fires. Here's a boiled down version of this page's declarative markup:
There are four key elements in the declarative markup:
- The ScriptManager control. As discussed in previous installments of this article series, the ScriptManager is the "engine" that is needed in every AJAX-enabled web page.
- The UpdatePanel control. This UpdatePanel includes a solitary Button control (
PartialPostbackButton) that, when clicked, performs a partial page postback. I also have created a server-side event handler for this Button control that executes the code
Thread.Sleep(5000), putting the thread to sleep for five seconds. This adds an artificial delay to the page so as to better illustrate what
PageRequestManagerobject events fire before the request to the server and afterwards.
- The UpdateProgress control. Displays a message during the five second delay on the server.
The first line of code gets an instance of the
PageRequestManager object. Next, the five
PageRequestManager object events are wired up to
five event handlers. Each of the five event handlers call the
logEvent function, passing in a message to display. The
innerHTML, appending the message and current time.
The three screenshots below show this demo in action. The first screenshot shows the page when it is first loaded. Note that the log output already contains one entry for
pageLoaded event. As noted earlier, the
pageLoaded event is raised whenever the page's contents have
been refreshed whether we are dealing with a full page postback (such as when the page is first visited or when a control outside of an UpdatePanel causes a postback) or a
partial page postback.
The second screenshot shows the page after the "Perform a Partial Postback" button has been clicked but before the server returns with its response. Note that the
UpdateProgress control is showing its message (the text in red). Also, two new client-side event handlers have fired:
When the response is returned from the web server the remaining
PageRequestManager object events fire:
endRequest. Here you see that the response has returned from the server: the UpdateProgress control is no longer displayed and the event log lists the
endRequest events. Notice that the
pageLoading event was raised five seconds after
beginRequest. This is because the server-side code that executes when the "Perform a Partial Postback" button is clicked sleeps for five seconds.
Aborting and Canceling Partial Page Postbacks
initializeRequestevent offers page developers an opportunity to cancel the postback, if needed. Furthermore, the
PageRequestManagerobject includes a function that, when executed, aborts all partial page postbacks, both those that are in progress and those that are queued up. To illustrate aborting and canceling postbacks, I created a demo similar to the one we just examined. In addition to the Button control, I added a Label in the UpdatePanel that displays the time the UpdatePanel was updated. Outside of the UpdatePanel I added two controls used for demoing the abort and cancel features:
- A CheckBox control named
CancelThisPostbackthat, if checked, causes the partial page postback to be canceled, and
- A button that, when clicked, aborts all outstanding postbacks.
PageRequestManager_initializeRequestevent handler, however, to cancel the partial page postback if the
CancelThisPostbackcheckbox is checked:
If the checkbox
CancelThisPostback is checked the partial page postback is canceled by calling
args.set_cancel(true); and a message is added to the
log indicating that the postback was canceled. To test out this functionality, visit the page and click the "Perform a Partial Postback" button. As before, the page progresses through the various steps and the output is displayed
in the client-side event handler log. Also, the time in the UpdatePanel is updated to the current time. Now, check the "Cancel this postback" checkbox and click the
"Perform a Partial Postback" button. This time no partial page postback occurs.
The following screenshot shows the output of the page when the "Cancel this postback" checkbox is checked. Note that the client-side event handler log has just three entries:
- pageLoaded - this was displayed when the page was first loaded
- initializeRequest - this was displayed when the "Perform a Partial Postback" button was clicked, thereby starting the partial postback life-cycle
- Postback canceled - the postback was canceled.
This approach allows you to cancel the current partial page postback from the
initializeRequest event handler. The ASP.NET AJAX Framework also allows you
to abort all outstanding partial page postback requests. To accomplish this call the
To demo using this functionality, I created the following client-side function, which is executed whenever the "Abort Outstanding Partial Page Postbacks" button is clicked.
To test this functionality, visit the demo page and click the "Perform a Partial Postback" button (with the "Cancel this postback" checkbox unchecked). This will start the
partial page postback life-cycle. After the UpdateProgress output appears, click the "Abort Outstanding Partial Page Postbacks." This will abort the current partial page postback
and immediately raise its
endRequest event. The following screenshot shows the client-side event handler log when the "Abort Outstanding Partial Page Postbacks"
button is clicked during a partial page postback. As you can see, the partial page postback started normally as its
events were raised, but during the processing on the server the postback was aborted. This caused the
endRequest event to be raised immediately.
Scrolling the Browser Window to a Particular HTML Element When the Partial Page Postback Completes
I was recently working with a colleague who was using AJAX in a database search page. Essentially, users would enter various filtering criteria into TextBox controls, click a "Show Results" button, and the results would be displayed in a sortable and pageable GridView beneath the TextBox controls. The TextBoxes and GridView were both in an UpdatePanel.
The page was laid out such that the "Show Results" button was at the bottom of the browser screen for users with low screen resolutions. After typing in search values into the TextBox controls and clicking the "Show Results" button, the GridView would be populated beneath the "Show Results" button, but these users would not see the results because they were "beneath the fold." In short, they needed to scroll down to see the results. But because AJAX provides such a smooth user experience, the users didn't realize that the page had been updated. There was no "flash" of the screen or other cue that their action - clicking the "Show Results" button - had done anything because the actual output was displayed further down on the page.
The solution was to automatically scroll the user's browser to a particular HTML element situated directly above the output. This scrolling needed to occur whenever the partial page postback concluded.
window object includes a
scrollTo(x, y) method that will scroll to a particular (x,y) coordinate. With a little bit of
script it's possible to determine the (x,y) coordinate of an HTML element. We found a script
ScrollToElement(element). We then called this method
passing in the HTML element to scroll to in the
endRequest event handler.
scrollHere passed into the
getElementById(id) function references a
<div> element on the page located above the
category drop-down list.
Check out the demos available for download at the end of this article to see this functionality in action. The two screenshots below provide a glimpse at its behavior. The first screenshot shows the page when it is first viewed. At the bottom of the fold is a drop-down list where the user can select a category. Once they've selected a category and clicked the "Display Matching Products" button a GridView is displayed beneath the drop-down list that lists those products that belong to the selected category.
By default, after clicking the "Display Matching Products" button the user's browser window would stay fixed in its current location. A user would have to manually scroll down to see the results and, if by chance the "Display Matching Products" button was already at the bottom of their browser window they might not realize that the report the requested was available further down on the screen.
With the script added to this page, the user's browser is automatically scrolled to show the results when the partial page postback completes.