Handling ASP.NET AJAX client-side events

UPDATE: I have left this article here for historical reasons but you should now consider ASP.NET Web Forms as obsolete due to it not supporting unit-testing and the amount of data that is passed between client and server. I recommend a modern web technology such as MVC 4 (or later) combined with javascript libraries such as jQuery and Knockout.

Client Events
There are a number of different client-side events which are fired before and after full and partial-postbacks, so it’s important to be familiar with them and know the sequence in which they occur so you can add appropriate handlers in your client script. The following JavaScript example shows a selection of event handlers you might typically use for client-side processing on an ASP.NET AJAX page (this is not an exhaustive list but shows the main ones). You will need to add an ASP.NET ScriptManager control to your web form markup for the events in the Sys namespace to be available. Also, it’s unlikely you would use all of these together in single page – this is just a demonstration.

Event Sequence
The most important aspect is knowing the sequence of events, as shown below. Note that Sys.Application.init is only called during full-postbacks, and Sys.Application.load is only called during partial-postbacks. This is not immediately obvious from the event names, so it’s worth remembering.

Another point to note is that from my own tests, jQuery.ready and window.onload only fire before pageLoad about 80% of the time for postbacks, so don’t write any functionality that depends on this order of events. However jQuery.ready always fires before window.onload because the DOM is always ready before the page has finished loading. These three events have their pros and cons: window.onload only occurs after the page is fully loaded (including images) so any changes you make such as showing/hiding elements will be visible after the page has rendered,  so jQuery.ready is a much better choice for this scenario. Whereas pageLoad is the most flexible because it fires on both full and partial-postbacks but you need to handle that in your code, to take the appropriate action.

Here is the typical sequence of events:

Postback:

  1. jQuery.ready
  2. window.onload
  3. pageLoad
  4. Sys.Application.init
  5. Sys.Application.unload (called when leaving/refreshing the page)

Partial-postback:

  1. Sys.WebForms.PageRequestManager.initializeRequest
  2. Sys.WebForms.PageRequestManager.beginRequest
  3. Sys.Application.load
  4. pageLoad
  5. Sys.WebForms.PageRequestManager.endRequest

Unlike postbacks, the sequence for partial-postback events is always guaranteed to fire in this order.

pageLoad
The reserved function names pageLoad and pageUnload are defined in the global namespace of the Microsoft AJAX JavaScript library (you don’t need to explicitly add handlers to use them). In the above script example, the predicate function get_isPartialLoad which is called in pageLoad is crucial because pageLoad occurs after every full and partial-postback, so you must distinguish between the two and only add event handlers in response to full-postbacks otherwise they will be called multiple times for the same event (a.k.a. delegate multi-casting).

Asynchronous Events
The Microsoft AJAX JavaScript library provides the Sys.WebForms.PageRequestManager class which fires the initializeRequest, beginRequest and endRequest events during partial-postbacks (i.e. when you use an UpdatePanel in conjunction with a ScriptManager). These events allow you to manage client-side processing during the lifetime of partial-postbacks but are not as flexible as if you supplied callback functions for specific AJAX asynchronous service method calls. This is yet another compromise of ease of use versus having to write more code.

Because initializeRequest, beginRequest and endRequest handlers will be called in response to all partial-postback originating from your page, you must identify the source of the postback yourself using the sender._postBackSettings.sourceElement.id property. A criticism of Microsoft at this point is that the PageRequestManager event handler parameters are not well documented, and I had to search several ASP.NET forums before finding the information I needed. It seems an oversight on Microsoft’s part because you will almost certainly have different client-side processing needs depending on which controls trigger partial-postbacks on your page.

Accessing Server Controls
Gaining access to a server control from within one of the event handlers shown above is a bit more tricky than usual because the page is in the process of being loaded/unloaded. Using $find in the normal way just returns null, e.g. $find("<%= myControlId.ClientID %>"). So you need to use an alternative syntax which works well if you are trying to access the source of a partial-postback in an asynchronous event handler, like so:

var controlId = sender._postBackSettings.sourceElement.id;
var control = $find(controlId, document.forms[0]);

Or better still, use a jQuery selector to query the DOM:

var controlId = sender._postBackSettings.sourceElement.id;
var control = $("#" + controlId)[0];

Advertisements

About Phil Munro

I have been developing commercial desktop and distributed web applications with Microsoft technologies since 1997.
This entry was posted in AJAX, ASP.NET Web Forms, Javascript, jQuery. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s