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

Maintaining Splitbar position on postback.

3 Answers 66 Views
Splitter
This is a migrated thread and some comments may be shown as answers.
Sean
Top achievements
Rank 2
Sean asked on 25 Jan 2011, 07:43 PM
Hi all,

I am attempting to maintain the position of a RadSplitBar on postback. I am able to maintain -a- position, but am having trouble progressing it further than that.

My understanding is this:

When the RadSplitBar is moved it's related RadPane's are resized. Therefore, I would like to capture the RadPane's resize event. Unfortunately, there is no server side handling of this by default. So, I must capture OnClientResized events. This puts me off into client-side javascripting, though...and writing to Session isn't a simplistic procedure.

Is there a simple way to run some server-side code after capturing the OnClientResized event?

Ideally, it would be something like this:

<telerik:RadCodeBlock ID="RadCodeBlock1" runat="server" >
    <script type="text/javascript">
        function OnClientResized(pane, arg) {
            pane.SaveState();
         
    </script>
</telerik:RadCodeBlock>

Where SaveState is server-side code I have written to record the pane's height and width to Session. Should I be looking into AJAX for this functionality? 

EDIT: (Disclaimer: This won't be very pretty.) I managed to do this, but it's quite the workaround. If you guys have any better ideas it would be appreciated.

Here's the gist of it:

<telerik:RadCodeBlock ID="RadCodeBlock1" runat="server" >
    <script type="text/javascript">
 
        function OnClientResized(pane, args) {
            var context = new Object();
            var paneIDandHeight = pane.get_id() + ',' + pane.get_height();
            //Context is just thrown away.
            CallSetDimensions(paneIDandHeight, context);
        }
 
        function CallbackOnSucceeded(result, context) {
        //Logging
        }
 
        function CallbackOnFailed(result, context) {
        //Logging
        }
    </script>
</telerik:RadCodeBlock>


public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            RegisterCallBackReference();
        }
 
        private void RegisterCallBackReference()
        {
            //Target: The name of a server Control that handles the client callback.
            //Argument: An argument passed from the client script to the server.
            //clientCallback: The name of the client event handler that receives the result of success.
            //context: Client script that is evaluated on the client prior to initating the callback.
            //clientErrorCallback: The name of the client event handler that handles an error.
            //useAsync: True/False asynchronous postback.
 
            String callBack = Page.ClientScript.GetCallbackEventReference(this, "arg", "CallbackOnSucceeded", "context", "CallbackOnFailed", true);
 
            String clientFunction = "function CallSetDimensions(arg, context){ " + callBack + "; }";
 
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Call To Server", clientFunction, true);
        }
 
        #region ICallbackEventHandler Members
        String returnValue;
        string ICallbackEventHandler.GetCallbackResult()
        {
            return returnValue;
        }
 
        void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
        {
            bool result = SetDimensions(eventArgument);
 
            if (result)
            {
                returnValue = "Success.";
            }
            else
            {
                returnValue = "Failure.";
            }
        }
        #endregion
 
        private bool SetDimensions(string args)
        {
            bool saveSuccessful = false;
 
            string[] paneIDandHeight = args.Split(',');
            string paneID = paneIDandHeight[0];
            string paneHeight = paneIDandHeight[1];
            RadPane pane = Utilities.FindControlRecursive(Page, paneID) as RadPane;
            int height = 0;
 
            int.TryParse(paneHeight, out height);
 
            if (!object.Equals(pane, null))
            {
                saveSuccessful = true;
                RadPaneSetting paneSetting = RadPaneSetting.GetSettings(pane);
                pane.Height = new Unit(height, UnitType.Pixel);
                SavePane(pane);
            }
 
            return saveSuccessful;
        }
    }

This code won't compile if you just copy/paste it, I'm using a lot of other helper functions, but if you're stuck with this problem this would be a good place to start. From here you'll need to look up the demo example on persisting state in session.

3 Answers, 1 is accepted

Sort by
0
Accepted
Dobromir
Telerik team
answered on 31 Jan 2011, 10:20 AM
Hi Sean,

By design, RadSplitter preserves its state over postbacks, however, in scenario where you have a splitter in master page and changing the content pages, the approach that you have taken is the recommended one.

In addition, you can take advantage of RadXmlHttpPanel to provide a partial page updates using callbacks.

All the best,
Dobromir
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
0
Tony
Top achievements
Rank 1
answered on 09 Feb 2011, 06:51 AM
Hi Sean. Depending on your needs, we have come up with a much simpler solution that preserves these values using cookies: if cookies aren't an option, or you absolutely need those values in the Session, you can ignore this reply, but for those who can make use of them, I share this in hopes it helps someone.

We have a splitter on a master page, with the left-hand pane used for navigation and the right-hand pane used for content - pretty straight-forward. We change the content of both panes depending on the page you are on. We use both post-backs and querystring vars for our pages, and there are several pages that are used within the master page, so replying on the persistence via post-back doesn't work for us.

Basically, there are three very simple javascript functions that are used to store the expanded/collapsed state and the size of the left-hand pane in cookies. The master page's Page_Load method uses those cookies to configure the splitter.

Javascript support functions:

function TreeExpanded(pane) {
     document.cookie = "splitter=expanded; path=/";
}
 
function TreeCollapsed(pane) {
     document.cookie = "splitter=collapsed; path=/";
}
 
function NavPaneResized(sender, args) {
    document.cookie = "splitbar=" + sender.get_width() + "; path=/";
}

Splitter control markup:

<telerik:RadSplitter ID="splitSplitter" runat="server" Width="100%" Height="100%" BorderSize="0"
        LiveResize="true" OnClientLoaded="SplitterLoaded" OnClientResized="SplitterResized">
    <telerik:RadPane ID="panTree" runat="server" Width="250px" OnClientCollapsed="TreeCollapsed"
            OnClientExpanded="TreeExpanded" OnClientResized="NavPaneResized">
        <div class="treediv">
            <asp:TreeView ID="treNav" runat="server" NodeIndent="15" ExpandDepth="0">
            </asp:TreeView>
        </div>
    </telerik:RadPane>
    <telerik:RadSplitBar ID="barSplitter" runat="server" CollapseMode="Forward" />
    <telerik:RadPane ID="panContent" runat="server" Width="100%">
        <div class="mastercontent">
            <asp:ContentPlaceHolder id="MasterContentPlaceHolder1" runat="server" />
        </div>
    </telerik:RadPane>
</telerik:RadSplitter>

Master page code in Page_Load method (Note, a bug fix for this code was entered on Feb 12, 2011):

Dim blnCollapsed As Boolean = False
Dim intWidth As Integer = 250
Try
    If (Request.Cookies("splitter").Value = "collapsed") Then
        blnCollapsed = True
    End If
Catch ex As Exception
Finally
    panTree.Collapsed = blnCollapsed
End Try

Try
    If (Request.Cookies("splitbar").Value > 0) Then
        intWidth = Request.Cookies("splitbar").Value
    End If
Catch ex As Exception
Finally
  panTree.Width = New Unit(intWidth & "px")
End Try


So basically, the left-hand pane has all of the useful markup: it sets the OnClientCollapsed, OnClientExpanded, and OnClientResized handlers to the javascript functions that are listed, which simply set one of two cookies. In the code for Page_Load, defaults are set, the cookies are retrieved, and then the splitter is configured appropriately. Hope that helps someone.
0
Jorge
Top achievements
Rank 1
answered on 21 Jul 2016, 05:39 PM

Tony,

Awesome solution, works perfectly for my scenario.

Thanks for posting. Save me a lot of time.

Tags
Splitter
Asked by
Sean
Top achievements
Rank 2
Answers by
Dobromir
Telerik team
Tony
Top achievements
Rank 1
Jorge
Top achievements
Rank 1
Share this question
or