65.9K
CodeProject is changing. Read more.
Home

Using JQuery ajax with UpdatePanels

Jan 28, 2012

CPOL
viewsIcon

37754

Updating UpdatePanels by calling JQuery.ajax() call

As you might know, JQuery and UpdatePanels are not friends. But some times we have to use JQuery.ajax() to design a small request(this could increase the permanence - smaller request means less bits to be transferred, and also a shorter waiting time between request and response.) In the same time we might need to use an UpdatePanel to hold some complex controls that change their appearance between round-trips. as you might know, an UpdatePanel is rendered as a block (a div or a span depending on the RenderMode Property) that redraws itself every time its registered for update. first we add the page markups.
<asp:Button ID="cmdBind" runat="server" Text="Bind Some Data"  />
<table width="100%">
    <tr>
        <td style="width: 50%">
            <asp:Label ID="lblLoading1" runat="server" Style="display: none;">Loading ...</asp:Label>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:Repeater ID="SomeDataRepeater" runat="server">
                        <HeaderTemplate>
                            <ul>
                        </HeaderTemplate>
                        <ItemTemplate>
                            <li>
                                <%#Eval("Data")%></li>
                        </ItemTemplate>
                        <FooterTemplate>
                            </ul>
                        </FooterTemplate>
                    </asp:Repeater>
                </ContentTemplate>
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="cmdBind" EventName="Click" />
                </Triggers>
            </asp:UpdatePanel>
        </td>
        <td style="width: 50%">
            <asp:Label ID="lblLoading2" runat="server" Style="display: none;">Loading ...</asp:Label>
            <asp:UpdatePanel ID="OtherDataPanel" runat="server" UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:Repeater ID="SomeOtherDataRepeater" runat="server">
                        <HeaderTemplate>
                            <ul>
                        </HeaderTemplate>
                        <ItemTemplate>
                            <li>
                                <%#Eval("Data")%></li>
                        </ItemTemplate>
                        <FooterTemplate>
                            </ul>
                        </FooterTemplate>
                    </asp:Repeater>
                </ContentTemplate>
            </asp:UpdatePanel>
        </td>
    </tr>
</table>
On Page.Load handler we should add the code cmdBind.OnClientClick = String.Format("javascript:$('#{0}').show();", lblLoading1.ClientID) to show the text "Loading ..." when we click the button cmdBind. Then on the handler we register to call the function BindSomeOtherDataRepeater() that will request the server again.
Private Sub cmdBind_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdBind.Click
    BindSomeDataRepeater()
    ScriptManager.RegisterStartupScript(Me, Me.GetType, "BindSomeOtherDataRepeater", "BindSomeOtherDataRepeater();", True)
End Sub
the data to send to the server should contain __EVENTTARGET and __EVENTARGUMENT to cause a regular post-back event.
function BindSomeOtherDataRepeater(){
        $('#<%= lblLoading1.ClientID %>').hide();
        $('#<%= lblLoading2.ClientID %>').show();
        $.ajax({
            type: "POST",
            url: "<%= ResolveClientUrl(Me.Request.CurrentExecutionFilePath) %>",
            dataType: 'text',
            data: GetData(),
            success: function (msg) {
                $("#<%= lblLoading2.ClientID %>").hide();
                UpdateOtherDataPanel(msg);
            }
        });
}
 function GetData() {
    return {
    __EVENTTARGET : '<%= Me.UniqueID %>',
    __EVENTARGUMENT : 'other'
    };
}
 function UpdateOtherDataPanel(msg) {
 var div = toElement(msg);
 $('#<%= OtherDataPanel.ClientID %>').html($(div).html());
}
 function toElement(html) {
 var div = document.createElement('div');
    div.innerHTML = html;
    var el = div.childNodes[0];
    div.removeChild(el);
    return el;
}
we can catch this event by implementing the interface IPostBackEventHandler.
Public Sub RaisePostBackEvent1(ByVal eventArgument As String) Implements System.Web.UI.IPostBackEventHandler.RaisePostBackEvent
    If eventArgument = "other" Then
        BindSomeOtherDataRepeater()
        UpdateOtherDataPanel()
    End If
End Sub
lastly we send the resulting html of the UpdatePanel in the response
Public Sub UpdateOtherDataPanel()
    Dim div As New HtmlGenericControl("div")
    div.Controls.Add(SomeOtherDataRepeater)

    Response.Clear()
    Response.ContentType = "text"

    Dim twriter As New IO.StringWriter
    Dim writer As New Html32TextWriter(twriter)
    div.RenderControl(writer)
    Response.Write(twriter.ToString())
    Response.End()

End Sub