Expanding size to fit dynamic content

17 posts, 1 answers
  1. James
    James avatar
    35 posts
    Member since:
    Apr 2010

    Posted 10 Jun 2011 Link to this post

    I have a scenario where I'd like to have a vertical splitter with two panes: one on the right, one on the left.

    Dynamic content is loaded into both panes.  The pane on the left has tree controls which can be expanded to vertically lengthen the page and the pane on the right has a data grid with resizable columns which can horizontally lengthen the size of the page. 

    There is a requirement that there are no scroll bars inside the splitter/panes and that the only content that can be clipped is the horizontal content in the left pane.  This means that the height will need to expand as needed in both panes and that the width would expand as needed in the right pane so that all content is visible without scrollbars.

    Is it possible to configure the splitter and panes to do this?


    Edit:
    I noticed using IE Developer Tools and viewing the html that the rad splitter is rendered as a table with the panes as divs inside of cells.  The pane divs appear to have an inline height and width that is apparently calculated and set in pixels.  If I change these values to 100% in the developer tool, I get the display I am looking for.   However, as soon as I move the splitter, they of course reset back to fixed pixels and the scroll bars reappear. 

  2. Answer
    Marin Bratanov
    Admin
    Marin Bratanov avatar
    3595 posts

    Posted 14 Jun 2011 Link to this post

    Hi James,

    I believe you will find the following KB article useful: http://www.telerik.com/support/kb/aspnet-ajax/splitter/initially-resize-the-radsplitter-according-to-its-content.aspx. It explains how to resize the splitter according to its content initially.

    You can adopt the same approach and also handle the OnColumnResized event of the RadGrid and the OnClientNodeExpanded event of the RadTreeView to resize the splitter accordingly.

    You can also set the RadPanes' Scrolling property to None as well to avoid having scrollbars.

    As for your last question - RadSplitter dynamically calculates its dimensions via JavaScript and can only take percentage values as its overall size in respect to its parent element.

    I hope this helps you advance in your project.



    All the best,
    Marin
    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. KN425000
    KN425000 avatar
    16 posts
    Member since:
    Aug 2010

    Posted 07 Jul 2011 Link to this post

    Marin:

    The solution you linked to seems to solve the issue for me when the page is refreshed, but not on initial load.  For me, when the page first loads, even though the RadGrid inside one of the RadPanes is loaded with, say, 30 rows, the splitter is capped at 400x400 and only the first N rows (e.g., 7) show.  The rest of the grid is cut off.

    When I refresh the page (F5), the splitter is resized correctly.

    There appears to be some sort of timing issue.  Can the splitter's OnClientLoaded event handler fire *before* the contents in the splitter (e.g., a RadGrid inside a RadPane) have finished loading?   If so, what's the proper way to handle this?
  5. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3595 posts

    Posted 08 Jul 2011 Link to this post

    Hi Mike,

    It is possible that the Splitter is initialized before its content if the content is heavy enough. The splitter is merely a container and does not have too much to render, unlike, for example, a Grid with many records.

    A possible workaround would be to use the pageLoad() function that is fired when all controls are loaded on the page and resize the Splitter there as well. You could also try setting the Splitter's VisibleDuringInit property to false.


    Greetings,
    Marin
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  6. KN425000
    KN425000 avatar
    16 posts
    Member since:
    Aug 2010

    Posted 08 Jul 2011 Link to this post


    The grid in question is "heavy" relative to the splitter.  VisibleDuringInit = "false" won't work while the grid is loading due to cosmetic reasons.

    Yeah, I figured out that I should do it in pageLoad, but thanks for validating that.

    When the splitter resizes to fit dynamic content, it "sticks" for a second in a partially collapsed state before expanding.  That's the last piece of the resizing puzzle.  Do you know how to handle that?

    Thanks!
  7. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3595 posts

    Posted 11 Jul 2011 Link to this post

    Hello Mike,

    I am glad that you found the solution yourself. As for the resizing delay - I am not sure what you mean by partially collapsed state, but I suppose you refer to the small delay between the content/browser resize and the actual resizing of the splitter. This happens because the Splitter has to recalculate all its dimensions on the client and replace the new ones in the markup. This is an operation that simply takes some time to complete and cannot be avoided. If that is not what you mean please explain in some more details the issue you are having and/or send us a video capture and/or screenshots with this behavior.


    Kind regards,
    Marin
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  8. KN425000
    KN425000 avatar
    16 posts
    Member since:
    Aug 2010

    Posted 11 Jul 2011 Link to this post


    Picture a splitter with two panes (left and right and a vertical split bar between them).  The left pane contains a tree view and the right pane contains a grid.   When the page loads, the left pane immediately appears at about 1/2 the width specified in the left pane's declaration, and the right pane does something similar.  Then, a split second later, both panes resize to the specified width. 

    I'm using the same declared width in the pane markup as well as the pageLoad event handler.
  9. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3595 posts

    Posted 12 Jul 2011 Link to this post

    Hello Mike,

      I am not sure I understand you correctly, but I believe that this is either the initial sizing of the splitter (for which I advised the VisibleDuringInit property), or it is also very probable that we are talking about the same delay while the new sizes are being calculated. You can confirm if it is one of these by turning off the property and calling the resizing functionality with a large timeout (for example a few seconds). If you are certain that this is some different issue please send us a simple, runnable project that isolates it so we can examine it locally and see the cause of the issue. 


    All the best,
    Marin
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  10. James
    James avatar
    35 posts
    Member since:
    Apr 2010

    Posted 12 Jul 2011 Link to this post

    Update:

    I used the approach suggested by Marin and was able to get the panes in the grid to resize automatically as I wanted them to.  I ended up needing to handle the following events in javascript for each of the panes:

    OnClientResized

     

    OnClientBeforeResize

     

    OnClientExpanded

     

    OnClientCollapsed

     

    OnClientBeforeCollapse

     

    OnClientBeforeExpand

    It was rather involved but I was able to get it to work just the way I wanted.   I also set the VisibleDuringInit to false because when it is first loaded the panes showed up smaller and then resized after a second or two.  I didn't like having all the blank white space on the screen while it was loading so I displayed a loading message that disappeared when panes were displayed.  I only had this problem when the page first loaded.

     

     

     

     

     

     

     

     

     


  11. Kevin
    Kevin avatar
    9 posts
    Member since:
    Jun 2011

    Posted 20 Jul 2011 Link to this post

    Marin
    I am trying to do the samething here but keep getting error. I am trying to set the width of a radpane based on a Treeview that is in that pane. I have attached what i have to see if you can see were i am going wrong. Want to set the width of the leftpane based on the treeview in it. anytime a node is expanded.

    <%@ Master Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="SideNavigation.master.vb"
        Inherits="WebPortal.SideNavigation" %>
      
    <asp:Content ID="sidemenu" ContentPlaceHolderID="sidenavigation" runat="server">
        <script language="javascript" type="text/javascript">
      
            function HighlightNode(value) {
                var tree = $find("<%= RadTreeView1.ClientID %>");
                var node = tree.findNodeByValue(value);
                if (node != null) {
                    node.startEdit();
                }
            }
      
            function SplitterLoaded(splitter, arg) {
                var pane = splitter.getPaneById('<%= LeftPane.ClientID %>');
                var width = pane.getContentElement().scrollwidth;
                splitter.set_width(width);
                pane.set_width(width);
            }
          
      
      
        </script>
        <div id="ParentDivElement" style="height: 100%; padding-top: 15px; background-color: #465157;">
            <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
      
            </telerik:RadAjaxManager>
            <telerik:RadSplitter ID="MainSplitter" runat="server" Height="100%" Width="100%"
                Orientation="Horizontal" VisibleDuringInit="false" >
                <telerik:RadPane ID="MainPane" runat="server" Scrolling="none" MinWidth="500">
                    <telerik:RadSplitter ID="NestedSplitter" runat="server" Skin="Outlook" LiveResize="true" >
                        <telerik:RadPane ID="LeftPane" runat="server" MinWidth="255" MaxWidth="400">
                            <!-- Place the content of the pane here -->
                            <div class="sidebar">
                                <div class="sbcorner sbTL">
                                </div>
                                <div class="sbcorner sbTR">
                                </div>
                                <div class="sbcorner sbBL">
                                </div>
                                <div class="sbcorner sbBR">
                                </div>
                                <div class="sbmaincontents">
                                    <h1 class="title2">
                                        Reporting</h1>
                                    <telerik:RadTreeView ID="RadTreeView1" runat="server" Skin="WebBlue" OnClientNodeExpanded="SplitterLoaded">
                                        <DataBindings>
                                            <telerik:RadTreeNodeBinding Expanded="True" />
                                        </DataBindings>
                                    </telerik:RadTreeView>
                                </div>
                            </div>
                        </telerik:RadPane>
                        <telerik:RadSplitBar ID="VerticalSplitBar" runat="server" CollapseMode="Forward" />
                        <telerik:RadPane ID="ContentPane" runat="server">
                            <!-- Place the content of the pane here -->
                            <div class="main">
                                <div class="corner TL">
                                </div>
                                <div class="corner TR">
                                </div>
                                <div class="corner BL">
                                </div>
                                <div class="corner BR">
                                </div>
                                <div class="maincontents">
                                    <asp:ContentPlaceHolder ID="MainContent" runat="server" />
                                </div>
                            </div>
                            <telerik:RadNotification ID="RadNotification1" runat="server" Animation="Fade" Position="BottomRight"
                                AutoCloseDelay="10000" Width="300" TitleIcon="warning" ContentIcon="warning">
                            </telerik:RadNotification>
                        </telerik:RadPane>
                    </telerik:RadSplitter>
                </telerik:RadPane>
            </telerik:RadSplitter>
        </div>
    </asp:Content>
  12. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3595 posts

    Posted 21 Jul 2011 Link to this post

    Hi Kevin,

    The issue here is that the sender of the function is not a RadSplitter, but a RadTreeView, thus the following line will cause an error, since the RadTreeView does not have the methods used:
    var pane = splitter.getPaneById('<%= LeftPane.ClientID %>');


    What I can suggest is that you use the $find() method to get a reference to the splitter first:
    function SplitterLoaded()
    {
        var splitter = $find("<%=NestedSplitter.ClientID %>");
        var pane = splitter.getPaneById('<%= LeftPane.ClientID %>');
         .....
    }



    Kind regards,
    Marin
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  13. Kevin
    Kevin avatar
    9 posts
    Member since:
    Jun 2011

    Posted 21 Jul 2011 Link to this post

    Thanks Marin
    The error i have been getting is attached. Once I changed to set the width instead of Height i started getting the error attached. Not sure waht is going on. Thanks for the Help.
  14. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3595 posts

    Posted 22 Jul 2011 Link to this post

    Hello Kevin,

    I see that in your previous post you have a splitter with Horizontal Orientation, which means that you need to use a different function to resize it. The error you get comes from the fact that you are trying to get the width of an object that does not have an explicit width (the horizontal pane). Please examine closely the following KB article to see the difference between a Horizontal and Vertical splitter: http://www.telerik.com/support/kb/aspnet-ajax/splitter/initially-resize-the-radsplitter-according-to-its-content.aspx.

    For your convenience I prepared a simple page that will resize a horizontal splitter when a treeview is expanded and collapsed. You can find it attached and here is a video with the expected behavior: http://screencast.com/t/2YKbkcOR. Please note my comments in the code and use this as a basis for your further development.


    Best wishes,
    Marin
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  15. Kevin
    Kevin avatar
    9 posts
    Member since:
    Jun 2011

    Posted 22 Jul 2011 Link to this post

    Thanks for the reply and your example work great but i am infact trying to set the width of the nested splitter and it is a vertical bar. I have tried to test on your code by changing to width on everything and then just setting the pane and splitter to the bounds.width but each time i click the pane gets smaller not larger.
    function resizeSplitter()
           {
               setTimeout(function ()
               {
                   var treeView = $find("<%=RadTreeView1.ClientID %>");
                   //gets a correct referece to the TreeView since it is not always the sender
                   var splitter = $find("<%=RadSplitter1.ClientID %>");
                   //get a correct reference to the Splitter, since the sender is not the Splitter, but the TreeView
                   var pane = splitter.getPaneById('<%= RadPane1.ClientID %>');
                   var bounds = $telerik.getBounds(treeView.get_element()); //this gets the actual size of the TreeView, even when it collapses
                   //as otherwise the height of the Radpane would remain too large, since it is already set
                   //this resizes the splitter, as shown in the KB article
                   pane.set_width(bounds.width);
                   splitter.set_width(bounds.width);
               }, 400);
               //some timeout to allow for the animation
           }
  16. Kevin
    Kevin avatar
    9 posts
    Member since:
    Jun 2011

    Posted 22 Jul 2011 Link to this post

    Marin,
    Well after some more testing i seam to have found issue. For some reason the getbounds method for the treeview is always returning the width from the pane and not the width of the treeview. If i look at the height at when expanding it does indeed change like expected but not the vaule for the width. Is this a bug in the treeview control or am i still doing something incorrect here. Again thanks for the time.
  17. Marin Bratanov
    Admin
    Marin Bratanov avatar
    3595 posts

    Posted 26 Jul 2011 Link to this post

    Hi Kevin,

      This issue is part of the reason why my demo changes the height. The RadTreeView renders as a div element and thus its width is 100% of it parent's width. This means that it is expected that the getBounds method will return the width of the pane when asked for the width of the RadTreeView, since they are the same.

      What I can suggest at this point to provide some usability is that you set a certain size for the pane that will contain the RadTreeView and in the OnClientNodeExpanded event scroll the last node into view, for example like this:
    function OnClientNodeExpanded(sender, args)
    {
        var nodes = args.get_node().get_nodes();
        var lastNode = nodes.getItem(nodes.get_count()-1);
        lastNode.scrollIntoView();
    }
    You can further extend this functionality by using the RadTreeView's API:
    http://www.telerik.com/help/aspnet-ajax/treeview-client-objects-radtreenode.html
    http://www.telerik.com/help/aspnet-ajax/treeview-client-objects-radtreeview.html

    An alternative solution is giving all the RadTreeView explicit dimensions so as to make sure it will not overflow the RadPane.

      By using the API and a lot of DOM traversal perhaps it is possible that you access all the child nodes' span elements that contain the text, then get the x offset and width for each of them   (again via the getBounds() method)  and copmare them, thus finding the one that extends farthest to the right, which will enable you to get the actual width of the RadTreeView. I cannot guarantee that this approach will work and that it will be trouble-free or easy to impelement, it is simply an idea. I hope you will be able to get this customized functionality working.

    Best wishes,
    Marin
    the Telerik team

    Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

  18. Kevin
    Kevin avatar
    9 posts
    Member since:
    Jun 2011

    Posted 26 Jul 2011 Link to this post

    Thanks for all of your help with this. I have gotten it to work like i want (kinda).
    Main thing is to be able to set the width of the pane to length of the longest tree node.
    The attached code does this during the data binding of the node.
    Its some code i found and use for sizing the combobox dropdown to fit longest strings.

    Again tahnks for the time and help.
    Protected Sub RadTreeView_OnNodeDataBound(ByVal sender As Object, ByVal e As RadTreeNodeEventArgs) Handles RadTreeView1.NodeDataBound
           Dim tree As RadTreeView = DirectCast(sender, RadTreeView)
           'set the width of the expanded tree nodes to the width of the longest string in the node collection
           Dim MaxWidth As Integer = 150
           For Each item As RadTreeNode In tree.GetAllNodes()
               Dim Width As Integer = TextWidth(item.Text)
               If Width > MaxWidth Then
                   MaxWidth = Width
               End If
           Next
           LeftPane.Width = New Unit(MaxWidth)
       End Sub
       Private Function TextWidth(ByVal TheText As [String]) As Integer
           'function used to measure the width needed to display a string value then control can be set to this width
           Dim DrawFont As Font = Nothing
           Dim DrawGraphics As Graphics = Nothing
           Dim TextBitmap As Bitmap = Nothing
           Try
               TextBitmap = New Bitmap(1, 1)
               DrawGraphics = Graphics.FromImage(TextBitmap)
               DrawFont = New Font("Segoe UI", 12)
               Dim Width As Integer = CInt(DrawGraphics.MeasureString(TheText, DrawFont).Width)
               Return Width
           Finally
               TextBitmap.Dispose()
               DrawFont.Dispose()
               DrawGraphics.Dispose()
           End Try
       End Function
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017