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

RadTreeView client-side scrollIntoView() for Selected Node Question

15 Answers 630 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Casey
Top achievements
Rank 1
Casey asked on 29 Sep 2009, 03:25 PM
Hello,

I'm currently using the client-side scrollIntoView() option to scroll to a node that is selected based on a user's search string. This is working, however, I'd like it to work a little bit differently and can't figure out how to achieve the desired functionality.

For example: The user searches and a match is found in the RadTreeView. The node is selected and the scrollIntoView() method is called. If the node that matches the search string is above the current scroll position, the SelectedNode appears at the top of the treeview. This is fine. What I would like to change is that if the node that matches is below the current scroll position then the SelectedNode appears at the bottom of the treeview. I would like the scrollIntoView method to automatically scroll so the SelectedNode is always at the TOP of the treeview, regardless of which way the SelectedNode was in relation to the current scroll position.

I have not been able to find out how to achieve this and I do not believe that it is built in either.

If anybody knows how to achieve this, I would greatly appreciate some guidance on what I need to do.

Thanks,
Casey

15 Answers, 1 is accepted

Sort by
0
Accepted
Peter
Telerik team
answered on 29 Sep 2009, 05:08 PM
Hi Casey,

You can achieve the desired functionality if you override the original _scrollToNode method of the treeview client object:

  _scrollToNode : function (node)  
    {         
        var nodeElement = node.get_contentElement();  
        var treeViewElement = this.get_element();  
          
        var nodeOffsetTop = this._getTotalOffsetTop(nodeElement);  
        var treeOffsetTop = this._getTotalOffsetTop(treeViewElement);  
        var relativeOffsetTop = nodeOffsetTop - treeOffsetTop;  
 
        if(relativeOffsetTop < treeViewElement.scrollTop)  
        {  
            treeViewElement.scrollTop = relativeOffsetTop;  
        }  
 
        var height = nodeElement.offsetHeight;  
          
        if(relativeOffsetTop + height > (treeViewElement.clientHeight + treeViewElement.scrollTop))  
        {  
            treeViewElement.scrollTop += ((relativeOffsetTop + height) - (treeViewElement.clientHeight + treeViewElement.scrollTop));  
        }  
    } 

Here is a simple example including the modification of the above method which achieves the desired functionality:
<asp:ScriptManager ID="ScriptManager1" runat="server">  
    </asp:ScriptManager>  
     
   <script type="text/javascript">  
        function OnClientItemClicked(sender, eventArgs)  
        {                       
            var treeview = $find('<%=RadTreeView1.ClientID %>');  
            var node = treeview.findNodeByValue("this")  
 
            scrollToNode(treeview, node);  
              
        }  
        function scrollToNode(treeview,node)  
        {   
            var nodeElement = node.get_contentElement();  
            var treeViewElement = treeview.get_element();  
              
            var nodeOffsetTop = treeview._getTotalOffsetTop(nodeElement);  
            var treeOffsetTop = treeview._getTotalOffsetTop(treeViewElement);  
            var relativeOffsetTop = nodeOffsetTop - treeOffsetTop;  
 
            treeViewElement.scrollTop = relativeOffsetTop;  
             
        }  
    </script>  
    <telerik:RadMenu ID="RadMenu1" OnClientItemClicked="OnClientItemClicked" runat="server">  
        <Items>  
            <telerik:RadMenuItem runat="server" Text="Scroll a specific node into view">  
            </telerik:RadMenuItem>  
        </Items>  
      
    </telerik:RadMenu>  
     <telerik:RadTreeView ID="RadTreeView1" Width="200px" Height="300px" runat="server">  
         <Nodes>  
              
            <%--more nodes here--%>  
             
             <telerik:RadTreeNode runat="server" Value="this" Text="THIS">               
             </telerik:RadTreeNode>  
               
             <%--more nodes here--%>  
                    
         </Nodes>     
     </telerik:RadTreeView> 


All the best,
Peter
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Casey
Top achievements
Rank 1
answered on 29 Sep 2009, 05:54 PM
Thanks Peter, that worked! I didn't have to change the original method though, it was the same except for the variable names.

I used the following javascript function:

function ScrollToNode() {  
                var treeview = $find("<%= RadTreeView1.ClientID %>");  
                if (treeview != null) {  
                    var node = treeview.get_selectedNode();  
                    if (node != null) {  
                        var nodeElement = node.get_contentElement();  
                        var treeViewElement = treeview.get_element();  
 
                        var nodeOffsetTop = treeview._getTotalOffsetTop(nodeElement);  
                        var treeOffsetTop = treeview._getTotalOffsetTop(treeViewElement);  
                        var relativeOffsetTop = nodeOffsetTop - treeOffsetTop;  
 
                        treeViewElement.scrollTop = relativeOffsetTop;  
                    }  
                }  
            } 

0
Casey
Top achievements
Rank 1
answered on 30 Sep 2009, 01:19 PM

Hi Peter,

I have another question related to this topic now. Along with being able to search for a node by text, the user has the ability to select a node by clicking it. The issue I am encountering now is that if the user clicks a node after searching for a node, the javascript will scroll the node just clicked by the user to the top.

In the FindNode method is there a way to call the javascript function to scroll to the node found by the search without setting the text property of the Label equal to the javascript function name? I tried setting the Label14.Text = "" in the Select_NodeClick method, but the node was still scrolled to the top. OR Is there a way to pass the node text to the javascript function to get the node by text instead of using get_selectedNode?

My code is below:

TreeView Definition:

<telerik:RadTreeView ID="RadTreeView1" runat="server"   
            AllowNodeEditing="True" DataFieldID="ORG_ID" 
                                    DataFieldParentID="PARENT_ORG_ID"   
            DataSourceID="SqlDataSource1" DataTextField="DESCRIPTION" 
                                    DataValueField="ORG_ID" EnableDragAndDrop="True" EnableDragAndDropBetweenNodes="True" 
                                    Height="400px" Width="400px"   
            LoadingStatusPosition="AfterNodeText"   
            OnNodeDrop="RadTreeView1_NodeDrop" OnNodeEdit="RadTreeView1_NodeEdit" OnNodeClick="Select_NodeClick">  
    </telerik:RadTreeView> 

Code Behind:

protected void Select_NodeClick(object sender, Telerik.Web.UI.RadTreeNodeEventArgs e)     
    {              
        e.Node.Selected = true;     
    }     
    
protected void Button_Click(object sender, EventArgs e)        
    {        
        int nodeCount = RadTreeView1.GetAllNodes().Count;        
        string SearchStr = TextBox1.Text; // Search string        
        FindNode(RadTreeView1, SearchStr, nodeCount);        
    }        
       
private void FindNode(RadTreeView tree, string searchString, int nodeCount)        
    {        
        Boolean selectedfound = false;        
        for (int i = (int)Session["NodeInt"] + 1; i < nodeCount; i++)        
        {        
            if (tree.GetAllNodes()[i].Text.ToUpper().Contains(searchString.ToUpper()))        
            {        
                tree.GetAllNodes()[i].Selected = true;        
                tree.GetAllNodes()[i].Focus();        
//save node location to enable "next" search functionality        
                Session.Add("NodeInt", i);        
                selectedfound = true;        
//if node is found, select it and call javascript function         
//to scroll to top of treeview        
                Label14.Text = "<script>Sys.Application.add_load(ScrollToNode);</script>";        
                return;        
            }        
        }        
//if node not found, display message and scroll back to top of treeview        
        if (selectedfound == false)        
        {        
            string radalertscript = "<script language='javascript'>function f(){radalert('<div><br /><br />No matches found.</div>', 250, 200); Sys.Application.remove_load(f);}; Sys.Application.add_load(f);</script>";        
            Page.ClientScript.RegisterStartupScript(this.GetType(), "radalert", radalertscript);          
            Session.Add("NodeInt", -1);        
            if (tree.SelectedNode == null)        
            {        
                Label14.Text = "<script>Sys.Application.add_load(ScrollToTop);</script>";        
            }        
            else         
            {        
                tree.SelectedNode.Selected = false;        
                Label14.Text = "<script>Sys.Application.add_load(ScrollToTop);</script>";        
            }        
        }        
    }   
 

Javascript:

function ScrollToNode() {  
                var treeview = $find("<%= radtreeview1.ClientID %>");  
                if (treeview != null) {  
                    var node = treeview.get_selectedNode();  
                    if (node != null) {  
                        var nodeElement = node.get_contentElement();  
                        var treeViewElement = treeview.get_element();  
 
                        var nodeOffsetTop = treeview._getTotalOffsetTop(nodeElement);  
                        var treeOffsetTop = treeview._getTotalOffsetTop(treeViewElement);  
                        var relativeOffsetTop = nodeOffsetTop - treeOffsetTop;  
 
                        treeViewElement.scrollTop = relativeOffsetTop;  
                    }  
                }  
            } 
function ScrollToTop() {  
                var tree = $find("<%= RadTreeView1.ClientID %>");  
                var node = tree.findNodeByText("Text");  
                if (node) {  
                    node.scrollIntoView();  
                }  
            } 
0
Peter
Telerik team
answered on 05 Oct 2009, 08:35 AM
Hi Casey,

I created a test page using your code, but I could not replicate the problem that you describe. Clicking a node didn't do anything. I suggest you open a support ticket and send us a simple demo which we can test locally.


Kind regards,
Peter
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Casey
Top achievements
Rank 1
answered on 05 Oct 2009, 11:49 AM
Hi Peter,

It looks like this was only happening because I was updating the treeview when an Ajax Request happened. If I remove the treeview from the Ajax Request, the click of a node will only select the node, not scroll it to the top.

Thanks,
Casey
0
Peter
Telerik team
answered on 06 Oct 2009, 02:52 PM
Hi Casey,

I am not sure if you have found a satisfactory solution for this case. Please, let us know if you need further assistance.

Best wishes,
Peter
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Casey
Top achievements
Rank 1
answered on 06 Oct 2009, 06:51 PM
Hi Peter,

Yes, I am satisfied with the answer I received. Once I was able to determine that the issue I was experiencing was related to the Ajax request against the tree I was able to resolve it.

Thanks again,
Casey
0
Chittaranjan
Top achievements
Rank 1
answered on 18 Feb 2011, 09:58 AM
Can I have the same functionality when the user checks a particular nodes i want to  scrollIntoView() after a postback.
 
This is my current code

function pageLoad() {

 

 

var tree = $find("<%= tvwAssetHierarchy.ClientID %>");

 

if (tree != null) {

 

 

var selectedNode = tree.get_selectedNode()

 

 

if (selectedNode != null) {

 

 window.setTimeout(

function() { selectedNode.scrollIntoView(); }, 480);

 

 }}}

But now what i want the user is checking the last node i want to Scrollintoview for the last checked node is it possible?
is there any method in the radtreeview which can give me the last checkednode or do i need to store it during the onclientradtreenodecheching event into a session variable and get that on the pageLoad event of the radtreeview.  Please suggest me on this.

 

0
Peter
Telerik team
answered on 21 Feb 2011, 11:32 AM
Hi Chittaranjan,

Yes, you need to keep track of the last checked node in an extra variable - just as you have thought of.


Best wishes,
Peter
the Telerik team
0
Mike Beaton
Top achievements
Rank 1
answered on 12 Apr 2011, 01:13 PM
Hi 

Is it possible to use the ScrollToNode example with the OnClientNodeExpanded event.

It does seem to work the same way (if at all).

Thanks

Mike
0
Peter
Telerik team
answered on 18 Apr 2011, 08:41 AM
Hi Mike,

Yes, it is possible, but you need to call scrollToNode with a slight delay like this:

<script type="text/javascript">
      
      function OnClientNodeExpanded(sender, args) {
          var treeview = sender;
          var node = treeview.findNodeByValue("this")
          setTimeout(function () { scrollToNode(treeview, node); }, 500);
      }
      function scrollToNode(treeview, node) {
          var nodeElement = node.get_contentElement();
          var treeViewElement = treeview.get_element();
          var nodeOffsetTop = treeview._getTotalOffsetTop(nodeElement);
          var treeOffsetTop = treeview._getTotalOffsetTop(treeViewElement);
          var relativeOffsetTop = nodeOffsetTop - treeOffsetTop;
          treeViewElement.scrollTop = relativeOffsetTop;
      }   
   </script>   
    
    <telerik:RadTreeView ID="RadTreeView1" Width="200px" Height="300px" runat="server" OnClientNodeExpanded="OnClientNodeExpanded">




Greetings,
Peter
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
Mike Beaton
Top achievements
Rank 1
answered on 20 Apr 2011, 09:43 AM
Thanks very much

Regards

Mike
0
Zahra
Top achievements
Rank 1
answered on 04 Jul 2011, 12:01 PM
Hi,

Just to say thanks for the scrollToNode(treeview, node) method. Your effort is appreciated very much.
0
mirang
Top achievements
Rank 1
answered on 26 Jan 2012, 03:34 AM
can i have a behavior in which only call scrolltoview if the searched node is out of the scrollarea of the treeview, so that if the node is within the scrollable and visible to the user dont scrolltoview
0
Peter
Telerik team
answered on 30 Jan 2012, 11:13 AM
Hi Mirang,

Probably, there is a way with jQuery or JavaScript to create your condition for this requirement. For example, the following thread might be helpful for this case - Determining if element is visible within a scrollable div.


Greetings,
Peter
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
Tags
TreeView
Asked by
Casey
Top achievements
Rank 1
Answers by
Peter
Telerik team
Casey
Top achievements
Rank 1
Chittaranjan
Top achievements
Rank 1
Mike Beaton
Top achievements
Rank 1
Zahra
Top achievements
Rank 1
mirang
Top achievements
Rank 1
Share this question
or