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
A SysAdmin's Guide to Change Management
 In the first in a series of monthly articles, ‘Confessions of a Sys Admin’, Matt describes the issues... Read more...

Exchange: Recovery Storage Groups
 It can happen at any time: You get a request, as Admin, from your company, to provide the contents of... Read more...

Build Your Own Virtualized Test Lab
 Desmon explains the fundamentals of building a test lab for Windows servers and Enterprise applications... Read more...

Rendering Hierarchical Data with the Treeview
 It sometimes happens that Web Server controls that visualize data don't quite fit with the way that... Read more...

SQL Server 2008: Performance Data Collector
 With Performance Data Collector in SQL Server 2008, you can now store performance data from a number of... Read more...