locked
Collapsible panels, Update panels and client side state RRS feed

  • Question

  • User-1205361351 posted

    Hi,

    I have a situation that I'm trying to resolve. Say you have a page with 3 collapsible panels. In a situation that an AJAX submission takes more than a couple of seconds a user could open and close the collapsible panels.  The panels then start to refresh to the state captured at the time of the AJAX submission and not to the current state.  This seems to be acceptable from a page that posts back to the sever, however, if you surround each collapsible panel inside an update panel then only the contained panels should fire the initialize event and maintained the client state.  Is there a way that I could do this?

    I have added the code as it now stands.  I hacked in a solution to the problem.

    client side:

    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="AJAXPage.aspx.vb" Inherits="AJAXEnabledWebApplication2.WebForm1" Theme="CollapsiblePanel"%>

    <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >

    <head id="Head1" runat="server">

    <title>Untitled Page</title>

    </head>

    <body>

    <form id="form1" runat="server">

    <asp:ScriptManager ID="ScriptManager1" runat="server" />

     

     

    <asp:UpdatePanel ID="UpdatePanel1" runat="server" >

    <ContentTemplate>

     

    <div onclick="doCallBack('UpdatePanel1','<%= CollapsiblePanelExtender1.SuppressPostBack %>' );">

    <asp:Panel ID="Panel2" runat="server" CssClass="collapsePanelHeader" Height="30px">

    <div style="padding:5px; cursor: pointer; vertical-align: middle;">

    <div style="float: left;">Case Details</div>

    <div style="float: left; margin-left: 20px;">

    <asp:Label ID="UpdateLabel1" runat="server" >(Show Details...)</asp:Label>

    </div>

    <div style="float: right; vertical-align: middle;">

    <asp:ImageButton ID="UpdateImage1" runat="server" ImageUrl="~/images/expand_blue.jpg" AlternateText="(Show Details...)" />

    </div>

    </div>

    </asp:Panel>

    <asp:Panel ID="Panel1" runat="server" CssClass="collapsePanel" Height="0">

    <asp:Label ID="Label3" runat="server"></asp:Label>

    <asp:Button ID="Button2" runat="server" Text="Button" />

    <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">

    <ProgressTemplate>

    Case Details updating....

    </ProgressTemplate>

    </asp:UpdateProgress>

    </asp:Panel>

     

     

    <ajaxToolkit:CollapsiblePanelExtender ID="CollapsiblePanelExtender1" runat="server"

    TargetControlID="Panel1"

    ExpandControlID="Panel2"

    CollapseControlID="Panel2"

    Collapsed="True"

    TextLabelID="UpdateLabel1"

    ImageControlID="UpdateImage1"

    ExpandedText="(Hide Details...)"

    CollapsedText="(Show Details...)"

    ExpandedImage="~/images/collapse_blue.jpg"

    CollapsedImage="~/images/expand_blue.jpg"

    SuppressPostBack="false"

    SkinID="CollapsiblePanelDemo"

    BehaviorID = "Update1"

    />

     

    </div>

    </ContentTemplate>

    </asp:UpdatePanel>

     

    <asp:UpdatePanel ID="UpdatePanel2" runat="server">

    <ContentTemplate>

    <div onclick="doCallBack('UpdatePanel2','<%= CollapsiblePanelExtender2.SuppressPostBack %>' );">

    <asp:Panel ID="Panel3" runat="server" CssClass="collapsePanelHeader" Height="30px">

    <div style="padding:5px; cursor: pointer; vertical-align: middle;">

    <div style="float: left;">Join Cases Details</div>

    <div style="float: left; margin-left: 20px;">

    <asp:Label ID="UpdateLabel2" runat="server" >(Show Details...)</asp:Label>

    </div>

    <div style="float: right; vertical-align: middle;">

    <asp:ImageButton ID="UpdateImage2" runat="server" ImageUrl="~/images/expand_blue.jpg" AlternateText="(Show Details...)" />

    </div>

    </div>

    </asp:Panel>

    <asp:Panel ID="Panel4" runat="server" CssClass="collapsePanel" Height="0">

    <asp:Label ID="Label4" runat="server"></asp:Label>

    <asp:UpdateProgress ID="UpdateProgress2" runat="server" AssociatedUpdatePanelID="UpdatePanel2">

    <ProgressTemplate>

    Join Cases Details updating....

    </ProgressTemplate>

    </asp:UpdateProgress>

    </asp:Panel>

     

     

    <ajaxToolkit:CollapsiblePanelExtender ID="CollapsiblePanelExtender2" runat="server"

    TargetControlID="Panel4"

    ExpandControlID="Panel3"

    CollapseControlID="Panel3"

    Collapsed="True"

    TextLabelID="UpdateLabel2"

    ImageControlID="UpdateImage2"

    ExpandedText="(Hide Details...)"

    CollapsedText="(Show Details...)"

    ExpandedImage="~/images/collapse_blue.jpg"

    CollapsedImage="~/images/expand_blue.jpg"

    SuppressPostBack="false"

    SkinID="CollapsiblePanelDemo"

    BehaviorID = "Update2"

    />

     

    </div>

    </ContentTemplate>

    </asp:UpdatePanel>

     

    <asp:UpdatePanel ID="UpdatePanel3" runat="server">

    <ContentTemplate>

    <div onclick="doCallBack('UpdatePanel3','<%= CollapsiblePanelExtender3.SuppressPostBack %>' );">

    <asp:Panel ID="Panel5" runat="server" CssClass="collapsePanelHeader" Height="30px">

    <div style="padding:5px; cursor: pointer; vertical-align: middle;">

    <div style="float: left;">Proceeding Details</div>

    <div style="float: left; margin-left: 20px;">

    <asp:Label ID="UpdateLabel3" runat="server" >(Show Details...)</asp:Label>

    </div>

    <div style="float: right; vertical-align: middle;">

    <asp:ImageButton ID="UpdateImage3" runat="server" ImageUrl="~/images/expand_blue.jpg" AlternateText="(Show Details...)" />

    </div>

    </div>

    </asp:Panel>

    <asp:Panel ID="Panel6" runat="server" CssClass="collapsePanel" Height="0">

    <asp:Label ID="Label6" runat="server"></asp:Label>

    <asp:UpdateProgress ID="UpdateProgress3" runat="server" AssociatedUpdatePanelID="UpdatePanel3">

    <ProgressTemplate>

    Proceeding Details updating....

    </ProgressTemplate>

    </asp:UpdateProgress>

    </asp:Panel>

     

     

    <ajaxToolkit:CollapsiblePanelExtender ID="CollapsiblePanelExtender3" runat="server"

    TargetControlID="Panel6"

    ExpandControlID="Panel5"

    CollapseControlID="Panel5"

    Collapsed="True"

    TextLabelID="UpdateLabel3"

    ImageControlID="UpdateImage3"

    ExpandedText="(Hide Details...)"

    CollapsedText="(Show Details...)"

    ExpandedImage="~/images/collapse_blue.jpg"

    CollapsedImage="~/images/expand_blue.jpg"

    SuppressPostBack="false"

    SkinID="CollapsiblePanelDemo" BehaviorID = "Update3"

     

    />

    </div>

    </ContentTemplate>

    </asp:UpdatePanel>

    <asp:Button ID="Button1" runat="server" Text="Button" />

     

    <div id="msg"></div>

     

    <script type="text/javascript">

     

    // initialize a panelQueue to synchronize AJAX requests

    var panelQueue = new Array();

    // one per panel to handle panel states with AJAX requests

    var isCollapsed1=true;

    var isCollapsed2=true;

    var isCollapsed3=true;var refreshState=false;

     

     

    // Function used to submit panels

    // value --> condition to post back or not (true=yes and false=no)

    // id --> id of the update panel

    function doCallBack(id,value) {

    if (value.toLowerCase()=="false") {

    __doPostBack(id,'');

    }

    }

    // Simple debugging -- added to bottom of page

    function AddMsg(msg){document.getElementById("msg").innerHTML = document.getElementById("msg").innerHTML + "<li>" + msg + "</li><br />";

    }

     

    // add handler for application loading

    Sys.Application.add_load(ApplicationLoadHandler);

     

     

     

     

    function ApplicationLoadHandler(sender, args)

    {

    var prm = Sys.WebForms.PageRequestManager.getInstance();if (!prm.get_isInAsyncPostBack())

    {

    // Only happens once during a page load and not AJAX completes.

    prm.add_initializeRequest(InitializeRequest);

    prm.add_endRequest(CompleteRequest);

    prm.add_pageLoading(pageLoadingHandler);

    prm.add_pageLoaded(pageLoadedHandler);

    }

    // Add extender events here. -- Extenders are always initialized and it is

    // necessary to reconnect the handlers.

    }

     

     

    function pageLoadedHandler(sender, args)

    {

    // Good one

    if ($find("Update1").get_Collapsed() != isCollapsed1)

    {

    $find(
    "Update1").set_Collapsed(isCollapsed1);

    }

    if ($find("Update2").get_Collapsed() != isCollapsed2)

    {

    $find(
    "Update2").set_Collapsed(isCollapsed2);

    }

    if ($find("Update3").get_Collapsed() != isCollapsed3)

    {

    $find(
    "Update3").set_Collapsed(isCollapsed3);

    }

    }

     

    function pageLoadingHandler(sender, args)

    {

    refreshState=
    true;

    isCollapsed1= $find("Update1").get_Collapsed();

    isCollapsed2= $find("Update2").get_Collapsed();isCollapsed3= $find("Update3").get_Collapsed();

    }

     

     

    function CompleteRequest(sender, args)

    {

    // handle the completed request

    if(panelQueue.length > 0){

    var selPanel =panelQueue[0].replace("Panel","");

    Array.removeAt(panelQueue, 0); // always remove initial

    $find(selPanel)._doOpen();

    }

    // call next panel in queue

    if(panelQueue.length > 0)

    {

    doCallBack(panelQueue[0],"false"); // do call back on next item

    // label all queued requests as pending

    for (i=0;i<panelQueue.length;i++)

    {

    var selLabel =panelQueue[i].replace("Panel","Label");

    var e = document.getElementById(selLabel);

    e.innerHTML = "(Pending...)";

    }

    }

    }

     

    function InitializeRequest(sender, args)

    {

    var prm = Sys.WebForms.PageRequestManager.getInstance();

    var selPanel =args.get_postBackElement().id;

    // kill all other request types

    if (selPanel.indexOf("UpdatePanel")==-1)

    {

    args.set_cancel(
    true);return;

    }

     

     

    selPanel = selPanel.replace("Image","Panel");// Handle image being pressed

    if (prm.get_isInAsyncPostBack())

    {// if it's working on another request, cache the current item that cause the request

    args.set_cancel(true);

     

    // Get div tag

    var selDiv =selPanel.replace("Panel","");

    $find(selDiv)._doClose();

    var e = document.getElementById(selPanel.replace("Panel","Label"));

    e.innerHTML = "(Pending...)";

    var found =false;for(var i=0;i<panelQueue.length;i++)

    {

     

    if (panelQueue[i] == selPanel)

    {

    found = true; // Panel already in queue

    }

    }

    if (!found) {AddMsg("Added to queue");

    Array.add(panelQueue, selPanel);

    }

    }

    else

    {

    if (panelQueue[0] != selPanel) { // handle auto post from queue in CompleteRequest function

    AddMsg("Added to queue");

    Array.add(panelQueue, selPanel);

    }

    }

    }

    if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

     

     

    </script>

    </form>

    </body>

    </html>

     

     

    Server side:

     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Me.IsPostBack Then

    If Me.ScriptManager1.IsInAsyncPostBack Then

    Dim s As String = ScriptManager1.AsyncPostBackSourceElementID

    Select Case s

    Case "UpdatePanel1" ', "Image1"

    Me.Label3.Text = Now.ToString

    Me.CollapsiblePanelExtender1.SuppressPostBack = True

    Case "UpdatePanel2" ', "Image2"

    Me.Label4.Text = Now.ToString

    Me.CollapsiblePanelExtender2.SuppressPostBack = True

    Case "UpdatePanel3" ', "Image3"

    Me.Label6.Text = Now.ToString

    Me.CollapsiblePanelExtender3.SuppressPostBack = True

    End Select

    System.Threading.Thread.Sleep(6000)

    End If

    End If

    End Sub

    Sunday, October 7, 2007 9:38 PM

Answers

  • User-1205361351 posted

    Solved my problem by setting the property UpdateMode to conditional on the update panels.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 9, 2007 10:42 PM

All replies

  • User-1205361351 posted

    Solved my problem by setting the property UpdateMode to conditional on the update panels.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 9, 2007 10:42 PM
  • User-1205361351 posted

    If any one is interested I could improve the code with the improvements.

    Wednesday, October 10, 2007 12:04 AM