Maintaining Splitbar position on postback.

4 posts, 1 answers
  1. Sean
    Sean avatar
    200 posts
    Member since:
    Nov 2010

    Posted 25 Jan 2011 Link to this post

    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.

  2. Answer
    Dobromir
    Admin
    Dobromir avatar
    1633 posts

    Posted 31 Jan 2011 Link to this post

    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.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Tony
    Tony avatar
    14 posts
    Member since:
    Sep 2010

    Posted 09 Feb 2011 Link to this post

    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.
  5. Jorge
    Jorge avatar
    1 posts
    Member since:
    Nov 2015

    Posted 21 Jul in reply to Tony Link to this post

    Tony,

    Awesome solution, works perfectly for my scenario.

    Thanks for posting. Save me a lot of time.

Back to Top