This is a migrated thread and some comments may be shown as answers.

Client state persistence across pages

9 Answers 173 Views
Splitter
This is a migrated thread and some comments may be shown as answers.
Adam
Top achievements
Rank 1
Adam asked on 17 Mar 2009, 09:58 PM

Hey guys.  I've taken a couple of stabs at this problem without too much luck yet.

Our scenario is a RadSplitter with two panes, left and right, with a dockable left hand RadSlidingPane hosted inside a MasterPage with the Content in the right hand pane.  The desired behavior is that, as a user would resize or dock the left hand side, that its state is persisted across postbacks and pages.  Since the resize events are not server events, we can't do any actual server processing on resize, so that only leaves client side methods.  We've tried cookies, but it seems as though, when moving from page to page, the cookies are duplicated from time to time so that we get page-specific cookies for the Request instead of only ever having one cookie there.  And, since there are now no client side methods that set the widths of anything other than the splitter, I don't see many other options left.

What solutions do you have for this set up?  

Thanks a lot,

Adam.g

9 Answers, 1 is accepted

Sort by
0
Accepted
Max
Top achievements
Rank 2
answered on 18 Mar 2009, 03:04 AM
I just tried to set this up using a asmx service linked off the master page and this works pretty well for me.  Only difference from your requirement is that is uses Session instead of cookies.

TelerikStateService.asmx:
namespace MyProject
{  
  [WebService(Namespace = 
"http://tempuri.org/")]  
  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]  
  [System.ComponentModel.ToolboxItem(false)]  
  [System.Web.Script.Services.ScriptService]  
  public class TelerikStateService : System.Web.Services.WebService  
  {  
    [WebMethod(EnableSession=true)]  
    public void TogglePane(string paneID, bool isCollapsed)  
    {  
      Session[paneID + "_Collapsed"] = isCollapsed;  
    }  
  }

Master page markup:

  <telerik:RadScriptManager ID="RadScriptManager1" runat="server" EnableScriptCombine="true">  
    <Services> 
      <asp:ServiceReference Path="~/TelerikStateService.asmx" /> 
    </Services> 
  </telerik:RadScriptManager> 
<telerik:RadSplitter ID="RadSplitter1" runat="server">  
  <telerik:RadPane ID="MyPane" OnClientCollapsed="CollapsePane" OnClientExpanded="ExpandPane" runat="server">  
    ...  
  </telerik:RadPane>  
</telerik:RadSplitter>

  <script type="text/javascript">    
    function CollapsePane(sender, args) {  
      MyProject.TelerikStateService.TogglePane(sender.get_id(), true);  
    }  
    function ExpandPane(sender, args) {  
      MyProject.TelerikStateService.TogglePane(sender.get_id(), false);  
    }
  </script> 

Master page Page_Load, call this method for each pane:
 
    public void LoadPaneSettings(RadPane pane)  
    {  
      bool paneCollapsed = (bool)(Session[pane.ClientID + "_Collapsed"] ?? false);        
      pane.Collapsed = paneCollapsed;  
    } 

Let me know if you can clean this up a bit for me ^.^
0
Tsvetie
Telerik team
answered on 20 Mar 2009, 01:26 PM
Hello Adam,
I am not quite sure how you implemented your cookies. In case you send me your code, I will review it and probably would find the cause for the duplication.

I have attached a simple test page that demonstrates one implementation of your scenario. I hope this would help you.

Sincerely yours,
Tsvetie
the Telerik team


Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Adam
Top achievements
Rank 1
answered on 20 Mar 2009, 04:42 PM

I love the cookie approach, and you're correct that the above example works great for preserving the docked state,
but we are attempting to store the width as well.  So, while there isn't a problem obtaining the width on the client side, there IS a problem setting the width on the client side.  I am unaware of a client side method that sets the RadSlidingPane's width on the client side, so I'm attempting to set the width on the server side, and therein lies the problem.

Expanding upon the original code to store the docking info and the width:

                var SplitterCookie = "SplitterCookie";  
                var SplitterCookieDelimiter = "*";  
                
                function PreserveState(sender, eventArgs)  
                {  
                    debugger;  
                    var zone = $find('<%= SlidingZone1.ClientID %>');  
                    var expandedPaneID = zone.get_dockedPaneId();  
                    expandedPaneID += SplitterCookieDelimiter + sender.get_width();  
                    SetCookie('SplitterCookie', expandedPaneID);  
                }  
                  
                function OnClientLoaded(object, args)  
                {  
                    var zone = object;  
                    var dockedPaneID = GetCookie('SplitterCookie');  
                      
                    if (dockedPaneID)   
                    {  
                      debugger;  
                      var docked = dockedPaneID.substring(0, dockedPaneID.indexOf(SplitterCookieDelimiter));  
                      if(docked)  
                      {  
                          setTimeout(function(){  
                              zone.dockPane(docked);  
                          }, 0);              
                      }  
                    }  
                } 

private const String _SPLITTERCOOKIENAME = @"SplitterCookie";  
    private const char _SPLITTERCOOKIEDELIMITER = '*';  
 
    /// <summary>  
    /// Gets the cookie used for storing the client persisted state of the Splitter  
    /// </summary>  
    private void GetSplitterPersistenceCookie()  
    {  
        HttpCookie cookie = Request.Cookies[_SPLITTERCOOKIENAME];  
 
        if (cookie != null)  
        {  
            string[] cookieValues = cookie.Value.Split(_SPLITTERCOOKIEDELIMITER);  
 
            Nav.Width = new Unit(Double.Parse(cookieValues[1]), UnitType.Pixel);  
        }  
    } 

When we attempt to retrieve the cookie on page_load of the master page, we often get the correct cookie value.  However, while going from page to page, we soon see a duplicate cookie, and so we end up retrieving an invalid value.

Any thoughts?

Adam.g

0
Tsvetie
Telerik team
answered on 24 Mar 2009, 02:37 PM
Hello Adam,
You can use the set_width client-side method of the RadSlidingPane to set the width of the sliding pane on the client. For example:
<telerik:RadSplitter ID="RadSplitter1" runat="server"
    <telerik:RadPane ID="RadPane1" runat="server" Width="22px"
        <telerik:RadSlidingZone ID="RadSlidingZone1" runat="server"
            <telerik:RadSlidingPane ID="RadSlidingPane1" Width="150" runat="server" Title="Pane 1"
            </telerik:RadSlidingPane> 
        </telerik:RadSlidingZone> 
    </telerik:RadPane> 
    <telerik:RadSplitBar ID="RadSPlitBar1" runat="server" /> 
    <telerik:RadPane ID="RadPane2" runat="server"
        <button onclick="SetSlidingPaneWidth(300);return false;">Set 300 px as width</button> 
    </telerik:RadPane> 
</telerik:RadSplitter> 
<script type="text/javascript"
function SetSlidingPaneWidth(newWidth) 
    var slidingPane = $find('<%= RadSlidingPane1.ClientID %>'); 
    slidingPane.set_width(newWidth); 
</script> 

Make sure that you first set the new width for the sliding pane and then dock it.

All the best,
Tsvetie
the Telerik team

Check out Telerik Trainer , the state of the art learning tool for Telerik products.
0
Michael Pullella
Top achievements
Rank 1
answered on 09 Aug 2010, 02:51 PM
"When we attempt to retrieve the cookie on page_load of the master page, we often get the correct cookie value.  However, while going from page to page, we soon see a duplicate cookie, and so we end up retrieving an invalid value."

I have taken this approach as well, and am finding the same problem that Adam had... How did / can you get around this?
0
Adam
Top achievements
Rank 1
answered on 09 Aug 2010, 02:56 PM
We gave up on checking cookies a long while back in the process and have not had any problems with the approach marked as answer in this thread.  If that approach is an option for you, I would highly recommend it.
0
Michael Pullella
Top achievements
Rank 1
answered on 09 Aug 2010, 03:01 PM
Adam..

When you say "gave up on checking cookies", what are you saying exactly? 

Right now, I'm doing this:
        function OnClientLoaded(object, args) {
            var zone = object;
            var dockedPaneID = getCookie('dockedID');
alert("setting pane to " + dockedPaneID);
            if (dockedPaneID) {
                setTimeout(function() {
                    zone.dockPane(dockedPaneID);
                }, 0);
            }
        }

are you saying that you are not getting the cookie (line above the alert)? 

Thanks in advance Adam!
0
Adam
Top achievements
Rank 1
answered on 09 Aug 2010, 03:06 PM
Yes, instead of getting and setting the Splitter settings on the client, we set them on load of the page.  So, instead of storing the data in cookies, we have a locally instanced service that we can call from javascript that sets session settings for the user.  It's very similar to Max's approach listed above.
0
Michael Pullella
Top achievements
Rank 1
answered on 09 Aug 2010, 03:23 PM
Thanks Adam..

For now, this approach isn't going to work, but I have changed the idea that Telerik gave and it seems to be working.  Basically, I just set an expiration on the cookie for 30 minutes.  Even though I have waited longer than 30 minutes between postbacks, the solution seems to still be working

function setCookie(name, value, minutes) {
    if (seconds) {
        var date = new Date();
        date.setTime(date.getTime() + (minutes * 60 * 1000));
        var expires = "; expires=" + date.toGMTString();
    }
    else var expires = "";
    document.cookie = name + "=" + value + expires + "; path=/";
}

function
PreserveState() {
    var zone = $find('<%= mainSlidingZone.ClientID %>');
    var expandedPaneID = zone.get_dockedPaneId();
    setCookie('dockedID', expandedPaneID, 30);
}

Thanks for your help Adam... If we find that this isn't going to work, I will take your advice and use Max's approach.
Tags
Splitter
Asked by
Adam
Top achievements
Rank 1
Answers by
Max
Top achievements
Rank 2
Tsvetie
Telerik team
Adam
Top achievements
Rank 1
Michael Pullella
Top achievements
Rank 1
Share this question
or