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

Expanding size to fit dynamic content

16 Answers 511 Views
Splitter
This is a migrated thread and some comments may be shown as answers.
James
Top achievements
Rank 1
James asked on 10 Jun 2011, 10:02 PM
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. 

16 Answers, 1 is accepted

Sort by
0
Accepted
Marin Bratanov
Telerik team
answered on 14 Jun 2011, 09:18 AM

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.

0
KN425000
Top achievements
Rank 1
answered on 07 Jul 2011, 01:36 PM
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?
0
Marin Bratanov
Telerik team
answered on 08 Jul 2011, 10:54 AM
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!

0
KN425000
Top achievements
Rank 1
answered on 08 Jul 2011, 04:17 PM

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!
0
Marin Bratanov
Telerik team
answered on 11 Jul 2011, 09:46 AM
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!

0
KN425000
Top achievements
Rank 1
answered on 11 Jul 2011, 01:42 PM

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.
0
Marin Bratanov
Telerik team
answered on 12 Jul 2011, 04:09 PM
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!

0
James
Top achievements
Rank 1
answered on 12 Jul 2011, 04:28 PM
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.

 

 

 

 

 

 

 

 

 


0
Kevin
Top achievements
Rank 1
answered on 20 Jul 2011, 03:15 PM
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>
0
Marin Bratanov
Telerik team
answered on 21 Jul 2011, 12:22 PM
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!

0
Kevin
Top achievements
Rank 1
answered on 21 Jul 2011, 12:48 PM
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.
0
Marin Bratanov
Telerik team
answered on 22 Jul 2011, 03:20 PM
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!

0
Kevin
Top achievements
Rank 1
answered on 22 Jul 2011, 03:50 PM
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
       }
0
Kevin
Top achievements
Rank 1
answered on 22 Jul 2011, 05:06 PM
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.
0
Marin Bratanov
Telerik team
answered on 26 Jul 2011, 01:18 PM
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!

0
Kevin
Top achievements
Rank 1
answered on 26 Jul 2011, 04:29 PM
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
Tags
Splitter
Asked by
James
Top achievements
Rank 1
Answers by
Marin Bratanov
Telerik team
KN425000
Top achievements
Rank 1
James
Top achievements
Rank 1
Kevin
Top achievements
Rank 1
Share this question
or