Home > AJAX, ASP.NET, jQuery > Using the AJAX UpdatePanel Control with jQuery

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();
                }
            });
  });
Categories: AJAX, ASP.NET, jQuery Tags: , , ,
  • http://www.dotnetkicks.com/aspnet/Using_the_ASP_NET_UpdatePanel_control_with_jQuery DotNetKicks.com

    Using the ASP.NET UpdatePanel control with jQuery…

    You’ve been kicked (a good thing) – Trackback from DotNetKicks.com…

  • http://www.drewpeterson.me Drew Peterson

    Another alternative is to use the livequery plugin http://docs.jquery.com/Plugins/livequery/livequery#matchedFn
    While not efficient if you plan on asynchronously loading hundreds of matching elements, it will fire the function you specify any time at matched element is loaded into the DOM. So in that case there would be no need to write the initAjax helper function, your normal jquery calls could just be rewritten as .livequery() calls.

  • http://blogs.dotnetkicks.com/vijayst vijayst

    I did some research on the livequery plugin. It works similarly to the .live() function that is introduced in jQuery 1.3.

    .live() function is extremely good in wiring jQuery event handlers for dynamically added elements. But, when an UpdatePanel is refreshed, the elements within the UpdatePanel is refreshed completely. There are a lot of initialization functions that have to be taken care of when an UpdatePanel is refreshed.

    For eg, take the case where a datepicker() widget has to be added to a TextBox. Since, this is an AJAX refresh, the load or ready event is not triggered on the TextBox. So, we cannot really apply a .live() function for initializations.

    That is why, I have recommended a simple design pattern for using jQuery with the AJAX UpdatePanel. This will ensure that all element initializations are taken care of. If initializations involve only writing event handlers, then .live() is a very good option. This is hardly the case for complex UI.

  • Chiana

    I reckon you are quite dead on with that.

  • Irish

    Frankly I think that’s absolutely good stuff.