Showing posts with label collapsible. Show all posts
Showing posts with label collapsible. Show all posts

Wednesday, March 28, 2012

ViewState of CollapsiblePanelExtender

I have several collapsible panels on a web form, and I cant seem to get them to remember their viewstate. Am I missing something or is this not possible?

Here is an example:

<asp:Content ID="Content2" ContentPlaceHolderID="DetailContentPage" Runat="Server"><div style="margin-left:10px"> <asp:Panel Width=100% ID="mainPanel" runat=server > <table width=100% align="left" cellspacing=0 cellpadding=10 > <tr> <td> <asp:Panel ID="ResHeaderPanel" runat="server" CssClass="formPanelHeader" Height="32px"> <div style="padding:5px; cursor: pointer;" > <div style="float:left; margin-top:4px;"> <asp:Image ID="imgResArrow" runat="server" ImageUrl="~/images/expand.jpg"/> </div> <div style="float:left; margin-left:6px; vertical-align:middle;">Engine Settings</div> <div style="float:left; margin-left:30px; margin-top:4px; font-size:x-small" > <asp:Label ID="lblResHeaderHint" runat="server">(Show Details...)</asp:Label> </div> </div> </asp:Panel> <asp:Panel ID="ResPanel" runat="server" CssClass="formPanel"> <table> <tr> <td width=200px>Number of Rooms:</td> <td width=70%><asp:TextBox ID="txtNumRooms" runat="server" MaxLength=200 width=70% /></td> </tr> <tr> <td>Time Zone: </td> <td><asp:TextBox ID="txtTimeZone" runat=server MaxLength=200 width=70%/></td> </tr> <tr> <td>form controls removed </td> <td></td> </tr> <tr> </table> </asp:Panel><!-- ******************************** --> <asp:Panel ID="ContactheaderPanel" runat="server" CssClass="formPanelHeader" Height="32px"> <div style="padding:5px; cursor: pointer;" > <div style="float:left; margin-top:4px;"> <asp:Image ID="Image1" runat="server" ImageUrl="~/images/expand.jpg"/> </div> <div style="float:left; margin-left:6px; vertical-align:middle;">Contact Details</div> <div style="float:left; margin-left:30px; margin-top:4px; font-size:x-small" > <asp:Label ID="lblContactHeaderHint" runat="server">(Show Details...)</asp:Label> </div> </div> </asp:Panel> <asp:Panel ID="ContactPanel" runat="server" CssClass="formPanel"> <table> <tr> <td width=200px>Address:</td> <td width=70%><asp:TextBox ID="txtAddress1" ReadOnly=false runat="server" MaxLength=200 width=70% /></td> </tr> <tr> <td>Address: </td> <td><asp:TextBox ID="txtAddress2" runat=server MaxLength=200 width=70%/></td> </tr> <tr> <td>form controls removed </td> <td></td> </tr> </table> </asp:Panel> </td> </tr> </table> <ajx:CollapsiblePanelExtender ID="cpeRes" runat="Server" TargetControlID="ResPanel" ExpandControlID="ResHeaderPanel" CollapseControlID="ResHeaderPanel" TextLabelID="lblResHeaderHint" ExpandedText=" " CollapsedText="(Click to Show Details...)" ImageControlID="imgResArrow" ExpandedImage="~/images/collapse.jpg" CollapsedImage="~/images/expand.jpg" EnableViewState=true SuppressPostBack="true" /> <ajx:CollapsiblePanelExtender ID="cpeContact" runat="Server" TargetControlID="ContactPanel" ExpandControlID="ContactHeaderPanel" CollapseControlID="ContactheaderPanel" TextLabelID="lblContactHeaderHint" ExpandedText=" " CollapsedText="(Click to Show Details...)" ImageControlID="imgContactArrow" ExpandedImage="~/images/collapse.jpg" CollapsedImage="~/images/expand.jpg" EnableViewState=true SuppressPostBack="true" /> </asp:Panel></div></asp:Content>
 
 
 -Steve 


I'm assuming your saying that when you open one, the other one closes. If so, try this: remove the "EnableViewState=true" from your code and wrap the entire thing in an update panel. I have similar yet I have no troubles with it but mine is wrapped in an update panel.


Thanks for the reply,

That is not quite what I was aiming for. I just wanted the state (open or closed) of the panels to be preserved after postbacks and navigation in my application.

I have a large form, that fills even a high res screen, I split the form into several collapsible panels, so that the user can show and hide the sections that are interesting. Then as the user navigates application records, and postbacks occur, I wish the state of each panel to be preserved.

Maybe I need to manually store the state to the Session and I am misunderstanding the scope of view state?


-Steve


If I understand correctly the panels are closed when you do a postback. This is because a postback reloads the controls. You want to do a partial postback, not a full postback. Therefore, wrap everything in an UpdatePanel, set the updatepanel's updatemode="conditional" and set the ScriptManager to enablepartialrendering="true"

This will cure the headache of a postback. Also with navigation it will have to be in updatepanels. Anything that does a postback must be eleminated and moved into the AJAX portion using update panels and such, otherwise the page will do a complete postback. Overall, the logic behind how things are to be setup with AJAX is a bit more work but the results is well worth it.

^_^


Thanks for the advice, this is the effect that I want to acheive, however I am using a Master page with content pages, linked to a site map based navigation. I trawled the web and could find no examples of the kind of site templete being used with AJAX.

Do have any advice for trying to achieve this? Otherwise the best solution would be to store the panels state to the Sessions, although this seems clunky and I would have thought that the controls would respect viewsate acress postbacks.

-Steve

Monday, March 26, 2012

want collapsiblePanel in user control to remember its state

Hi,

I am using the ajax collapsible panel extender. Is there a way to remember the state of the collapsible panels?...

basically i am using it as part of a side navigation, the sidenavigation is a user control and is used on every webpage of the site. when i click the hyperlinks (contained within the panels that extend) the page navigates to the new page and all the panels collapse. i can see how this can get frustrating to users. so is there a way that it can remember what state it is in??

thanks

Hi,

According to your description, you want to maintain the state of collapsible panels between different pages, isn't it?

In order to implement this, you need to save the state in a place out of the scope of a page, so that it can't be shared among different pages. Cookie, Session, or Profile will be good choices for you.

By default, the state is saved in ViewState or some additional HiddenField. The problem with them is that they are inside a page, and are always transfered to the server with POST http request. When it's redirected to a new page with GET request, those values will not be available in the new page. So, storages that doesn't rely on a specific page should be used.


yes i want it to remember the state across different webpages.

Can you guide me further with what i may need to do?...can i do this by assigning something to a session variable? if so what must i assign?and what must i do to open the new page with the newly assigned state?

thanks


You can save the state in session. For example, Session["cp1State"] = ture; // indicates collapsibelPanel1 is expanded.

Another thing you need to do is use javascript to invoke a web service to save current state in session. This javascript will work as the expanded and collapsed event handler for the corresponding CollapsiblePanelBehavior.


Hello Raymond,

Please can you give further details with the web service i need. i dont really know about web services...are there any examples used in conjunction with collapsiblePanel?

thanks


Here is a sample:

<%@. Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server">[System.Web.Services.WebMethod] public static void SaveState(string state) { HttpSessionState session = HttpContext.Current.Session; session["State"] = state; } protected void Page_Load(object sender, EventArgs e) { string script = @."function pageLoad(sender, args) { {0} $find('cpe2Behavior').add_collapsed(onCollapsed); $find('cpe2Behavior').add_expanded(onExpanded); }"; if (Session["State"] != null && Session["State"].ToString() == "expanded") { script = script.Replace("{0}", "$find('" + CollapsiblePanelExtender2.BehaviorID + "').expandPanel();"); } else { script = script.Replace("{0}", ""); } ScriptManager.RegisterStartupScript(this, this.GetType(), "expand", script, true); }</script><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"> </asp:ScriptManager> <asp:Panel ID="panel4" runat="server" > <asp:LinkButton ID="lnk2" runat="server" Text="Show Details"/> </asp:Panel>  <!--Content to show--> <asp:Panel id="panel3" runat="server"> Content </asp:Panel> <ajaxToolkit:CollapsiblePanelExtender SuppressPostBack="true" ID="CollapsiblePanelExtender2" BehaviorID="cpe2Behavior" runat="server" TargetControlID="panel3" ExpandControlID="panel4" CollapseControlID="Panel4" Collapsed="True" TextLabelID="lnk2" CollapsedText="Show Details.." ExpandedText="Hide Details.." > </ajaxToolkit:CollapsiblePanelExtender> <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Default3.aspx">Redirect to me</asp:HyperLink></div> <script type="text/javascript"> function pageLoad(sender, args) { $find("cpe2Behavior").add_collapsed(onCollapsed); $find("cpe2Behavior").add_expanded(onExpanded); } function onCollapsed(sender, args) { PageMethods.SaveState("collpased"); } function onExpanded(sender, args) { PageMethods.SaveState("expanded"); } </script> </form></body></html>

Saturday, March 24, 2012

Way to hold state of collapsible panel?

I've created a website application with a MasterPage that has an Accordion side-menu contained in a Collapsible Panel. It works fine, however, I need a way to hold the state of these controls when the user is redirected to another page.

So, if they have the side-menu collapsed and click a link to another page, when the new page is displayed, the side-menu should remained collapsed...is there anyway to do this? Basically, I just need to set some Session Variables to hold the state whenever the user manipulates the side-menu...

You could probably do it in viewstate? I don't have time to test it out right now, I'll try to get back to this later if nobody else has answered. Basically after you open a collapsible panel you could set something like viewstate("thiscontrolisCollapsed")=false and then on the page load you could do something like

if viewstate("isCollapsed")=false then

' code to open panel

end if

just off the top of my head. Sorry I can't be more technical with it, I'm getting ready to walk out the door and thought I'd throw this out as a suggestion.


Thanks, but the problem is actually being able to hold the state of the collapsible panel on the server side. All the collapsing and expanding is handled in client side javascript, and I'd need to somehow run some server-side code to hold the state after the client script has expanded or collapsed the panel.

I was thinking I need to fire off a client side call-back, but I can't figure out how to trigger it when the collapsible panel is expanded or collapsed...


Ok, I've figured out how to accomplish this. I already had an image that was the ExpandControlID and CollapseControlID, that the user clicks on to expand or collapse the panel. So I simply added an onclick attribute to that image which calls a javascript that initiates a client side call-back, where I pass the Collapsed status of the panel to the server and set a session variable. My code is below:

<script type="text/javascript" >
function holdSideMenuState(){
holdSideMenuStateInSession(!$find("SideMenuBehavior").get_Collapsed());
}

function sessionNowHoldsSideMenuState(isSideMenuCollapsed, context){
alert(isSideMenuCollapsed);
}
</script>
<table border="0" cellpadding="0" cellspacing="0" class="SideMenu">
<tr>
<td class="SideMenuExpandCollapse" valign="top">
<asp:Image ID="imgExpandCollapse" runat="Server" ImageUrl="~/images/collapse.jpg" CssClass="ExpandCollapseImage" />
</td>
<td>
<asp:Panel ID="pnlSideMenu" runat="Server">
Side Menu Content goes here....
</asp:Panel>
</td>
</tr>
</table
<ajaxToolkit:CollapsiblePanelExtender ID="cpeSideMenu" runat="server"
TargetControlID="pnlSideMenu"
CollapsedSize="0"
Collapsed="False"
ExpandControlID="imgExpandCollapse"
CollapseControlID="imgExpandCollapse"
AutoCollapse="False"
AutoExpand="False"
ScrollContents="False"
ImageControlID="imgExpandCollapse"
ExpandedImage="~/images/collapse.jpg"
CollapsedImage="~/images/expand.jpg"
ExpandDirection="Horizontal"
BehaviorID="SideMenuBehavior">
</ajaxToolkit:CollapsiblePanelExtender>


protected void Page_Load(object sender, EventArgs e)
{
string callBackReference = Page.ClientScript.GetCallbackEventReference(this,"isSideMenuCollapsed","sessionNowHoldsSideMenuState","context");
string callBackScript ="function holdSideMenuStateInSession(isSideMenuCollapsed, context){" + callBackReference +"}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"holdSideMenuStateInSession", callBackScript,true);

imgExpandCollapse.Attributes["onclick"] +="holdSideMenuState();";

if (!IsPostBack)
{
if (Session["IsSideMenuCollapsed"] ==null) Session["IsSideMenuCollapsed"] =false;

cpeMenu.Collapsed = Convert.ToBoolean(Session["IsSideMenuCollapsed"]);
}
}

public void RaiseCallbackEvent(string isSideMenuCollapsed)
{
Session["IsSideMenuCollapsed"] = isSideMenuCollapsed;
}

public string GetCallbackResult()
{
return Session["IsSideMenuCollapsed"].ToString();
}


I have some more work to do because in my real code, I actually have an Accordion inside the collapsible panel, and I need to hold the state of the accordion as well, but I'll save any questions I have with that for another thread...