Damon Armstrong

Caffeine Induced Tirades about .NET and Life
And don't forget to check out my latest Simple-Talk articles
Add to Technorati Favorites      Add to Google     

Saving the Telerik RadSplitter/RadPane State

Published Friday, December 22, 2006 8:31 AM

Telerik makes UI controls for ASP.NET (and they are getting in Windows Forms controls too apparently) and they've done a great job.   But, everything has it's little quirks.  I was working with the RadSplitter, a control that allows you to make collapsable / resizable panels on your webpage, when I ran across a little problem: persisting the state to a cookie.

The cool thing about the RadSplitter is that you can resize / collapse a pane on the Client-Side, and the control will use JavaScript to update hidden fields on the page so it sends the new size and collapse state back to the server.  We wanted to store that state in a cookie so when users closed the browser and returned, the resizable sections would retain their last size and collapse state.

Here's the issue:  let's say you have a pane that, by default, is 200px wide.  You resize that pane on the client side to 350px, then collapse it (hide it).  When you post the page back to the server, the pane reports its width as 0px.  So, how do you save the width of an updated pane when it's in a collapsed state?

The answer lies in the ExpandedWidth property, which is an internal value to the control that is not publicly exposed.  When a pane is collapsed, the ExpandedWidth property holds the width to which the pane should expand when expanded.  ExpandedWidht is 0px when the pane is fully expanded.

So, how do you get this value?  All of the state information about a RadPane comes back in as a JavaScript Object Notation (JSON) string in a hidden field, which we can intercept and parse to acquire the ExpandedWidth property (or whatever other property you want to find).  Here's the code to save and load pane state for a RadPane in a RadSplitter:

/// <summary>
/// Regular expression used to parse JSON object info comming back from the Telerik splitter control. Telerik did not expose
/// the expandedWidth property (which stores the width of the pane when it is collapsed) so you have to acquire it using a workaround
/// </summary>
private static Regex SplitterRegex = new System.Text.RegularExpressions.Regex("(?:\"collapsed\":(?<collapsed>[^,\\}]*))(?:.*)(?:\"expandedSize\":(?<expandedSize>[^,\\}]*))", RegexOptions.IgnoreCase);


/// <summary>
/// Saves splitter settings to the setting cookie
/// </summary>
private void SaveSplitterSettings()
{
    if (splitter != null)
    {
        string splitterStateString = Page.Request.Form[paneLeft.ClientID];
        if(!string.IsNullOrEmpty(splitterStateString))
        {
            Match match = SplitterRegex.Match(splitterStateString);
            if (match.Success)
            {
                try
                {
                    bool collapsed = bool.Parse(match.Groups[1].Value);
                    string width;
                    if (collapsed)
                    {
                        width = match.Groups[2].Value +
"px";
                    }
                    else
                    {
                        width = paneLeft.Width.ToString();
                    }
                    HttpCookie settingCookie = new HttpCookie("iswSplitterSettings");
                    settingCookie.Values.Add(
"LW", width);
                    settingCookie.Values.Add(
"LS", collapsed ? "1" : "0");
                    Page.Response.Cookies.Add(settingCookie);
                }
                catch
                {
                    //Do nothing
                }
            }
        }
    }
}


/// <summary>
/// Loads splitter settings from the setting cookie
/// </summary>
private void LoadSplitterSettings()
{
    HttpCookie settingCookie = Page.Request.Cookies["iswSplitterSettings"];
    if (settingCookie != null)
    {
        try
        {
            paneLeft.Width =
new Unit(settingCookie.Values["LW"].ToString());
            paneLeft.InitiallyCollapsed = (
bool)(settingCookie.Values["LS"] == "1");
        }
        catch
        {
            //Do nothing - allow the control to sort itself out
        }
    }
}

by Damon
Filed Under:

Comments

 

sheepie21 said:

I used your method and it worked great except one piece needed to be modified.

In the save method:
paneLeft.ClientID

needed to be

paneLeft.UniqueID

At least I had to change it for it to work with my site. The only thing I can think of as to why it would need to change is that my site has the RAD Splitter on a Masterpage not a Content page and that might change the form element id's.
April 17, 2007 4:36 PM
You need to sign in to comment on this blog

















<December 2006>
SuMoTuWeThFrSa
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
Virtual Exchange Servers
 Microsoft now supports running Exchange Server 2007 in server virtualization environments, not just on... Read more...

Virtualizing Exchange: points for discussion
 With the increasing acceptance of the use of Virtualization as a means of providing server... Read more...

Encouraging .NET Reflector Add-ins
 Jason Haley is well-known for the resources he's provided to developers who wish to extend Reflector's... Read more...

Using .NET Reflector Add-ins
 .NET Reflector by itself is great, but it really comes into its own with the help of some add-ins. Here... Read more...

Unique Experiences!
 You'd have thought that a unique constraint was an easy concept - Not a bit of it; it can cause a lot... Read more...