Using the AJAX UpdatePanel Control with jQuery
AJAX UpdatePanel is the most popular and the most widely used server control in the Microsoft AJAX stack. As you know, UpdatePanel is used to refresh portions of the page asynchronously. The following code shows how to use the UpdatePanel.
<asp:UpdatePanel ID="upnMain" runat="server">
<ContentTemplate>
<fieldset>
<legend>UpdatePanel</legend>
<div>
Name:
</div>
<div>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
</div>
<div>
<asp:Button ID="btnSave" Text="Save" runat="server" />
</div>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
The UpdatePanel takes care of preparing the AJAX request. This includes packing all of the form data (like textbox, Viewstate) into the Request body. The UpdatePanel makes an asynchronous call to the page and receives the response. The response data contains only the portion of the page within the UpdatePanel. The end-user gets a flicker-free experience on the page (thanks to AJAX).
In the above code, in addition to the TextBox control and the Button control, we can add a CheckBox control. When the user selects the CheckBox, the TextBox is enabled. If the user deselects the CheckBox, the TextBox is disabled. This is a common requirement in most web pages requiring user input.
<asp:UpdatePanel ID="upnMain" runat="server">
<ContentTemplate>
<fieldset>
<legend>UpdatePanel</legend>
<div>
Name:
</div>
<div>
<asp:CheckBox ID="chkName" runat="server" />
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
</div>
<div>
<asp:Button ID="btnSave" Text="Save" runat="server" />
</div>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
To do client-side programming, we have to make use of Javascript. jQuery is a popular javascript framework that can help us write cross-browser compatible code. All HTML elements in a page have a set of events corresponding to user actions on the page. jQuery can help us write event handlers for those user actions. For a checkbox, the user click action can be written to implement the above functionality.
// event fired when document is fully loaded
$(document).ready(
function () {
// event handler for the checkbox click event
$('input[name$=chkName]').click(
function () {
// enable / disable textbox on checkbox click
if ($(this).is(':checked'))
$('input[name$=txtName]').removeAttr('disabled');
else
$('input[name$=txtName]').attr('disabled', 'disabled');
});
});
The above code works perfectly for normal web pages. But, if jQuery code is embedded in a page with UpdatePanel, it does not work. Why is that? A portion of the page is refreshed by the UpdatePanel. So, the event handlers written for that portion of the page will not be valid. All the event handlers written for the HTML elements within the UpdatePanel have to be rewired again.
To do this, we can move the event handlers for the HTML elements within the UpdatePanel to a new function called initAjax(). This should be called each time an AJAX request is complete. The Microsoft AJAX Library contains a javascript class called the PageRequestManager which exposes an event handler for doing these things. It has events like initializeRequest, beginRequest, pageLoading, pageLoaded, and endRequest. When the request ends, the endRequest event handler is fired. Within this event handler, we can write code to reinitialize all jQuery event handlers like the Checkbox click. The code below shows how this can be done:
// initializes the event handlers for HTML elements
// within the UpdatePanel
function initAjax () {
// event handler for the checkbox click event
$('input[name$=chkName]').click(
function () {
// enable / disable textbox on checkbox click
if ($(this).is(':checked'))
$('input[name$=txtName]').removeAttr('disabled');
else
$('input[name$=txtName]').attr('disabled', 'disabled');
});
// write some more code for setting textbox enable / disable
// based on checkbox state (after user clicks save)
if ($('input[name$=chkName]').is(':checked'))
$('input[name$=txtName]').removeAttr('disabled');
else
$('input[name$=txtName]').attr('disabled', 'disabled');
}
// event fired when document is fully loaded
$(document).ready(
function () {
initAjax();
// Get the page request manager
var prm = Sys.WebForms.PageRequestManager.getInstance();
// Initialize the event handlers for the HTML elements within UpdatePanel
// Sets the endRequest event handler
prm.add_endRequest(initAjax);
});
The above code illustrates the normal pattern of code while using jQuery with a single UpdatePanel. If you have multiple UpdatePanels, you will have a initPanel1, initPanel2 etc for each UpdatePanel. The endRequest event handler has to be fine-tuned to call only the initialization functions for that UpdatePanel:
function initPanel1 {}
function initPanel2 {}
function initPanel3 {}
var btn;
$(document).ready(
function() {
initPanel1();
initPanel2();
initPanel3();
prm.add_beginRequest(
function (sender, args) {
btn = args.get_postBackElement().id;
});
prm.add_endRequest(
function (sender, args) {
if (btn.IndexOf("btnUpdatePanel1") > 0) {
initPanel1();
}
if (btn.IndexOf("btnUpdatePanel2") > 0) {
initPanel2();
}
if (btn.IndexOf("btnUpdatePanel3") > 0) {
initPanel3();
}
});
});