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

Filter Tree as User Control, Javascript Issues

3 Answers 114 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Steve
Top achievements
Rank 1
Steve asked on 07 Aug 2013, 11:13 AM
Hi,

I have followed the example code for filtering a RadTreeView using a RadTextBox as you type into the box, and it works a charm.  The link to that example is here: Filter Tree

I am using Telerik version: 2013.2.611.40

The issue I have is that my tree and textbox are in a user control, and on the same page I have two versions of this control.  When I type into the first textbox to filter the first tree nothing happens, but the second tree does expand.  The second tree works fine.

I know this is an issue with the valueChanged javascript function being called twice, but I cannot figure out a way around it, as this is hooked up the the keydown event on the textbox as a delegate (i think).

I have looked through plenty of articles saying to pass through the target, or to implement INamingContainer but nothing I do seems to sort this issue out.

Can anyone point me in the right direction?

Screenshots attached showing issue:

Screen 1 - page first loaded and both tree, fully collapsed.
Screen 2 - enter character into first textbox, and second tree expands.
Screen 3 - enter character into second textbox, and second tree filters as expected.

Demo project code below:

Master Page:

<%@ Master Language="VB" AutoEventWireup="false" CodeBehind="TestTree.master.vb" Inherits="TestTreeViewFiltering.TestTree" %>
 
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
 
<!DOCTYPE html>
 
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <telerik:RadScriptManager ID="RadScriptManager1" runat="server"></telerik:RadScriptManager>
        <div>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
         
            </asp:ContentPlaceHolder>
        </div>
    </form>
</body>
</html>

Web Page:

<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/TestTree.Master" CodeBehind="TestFilterTree.aspx.vb" Inherits="TestTreeViewFiltering.TestFilterTree" %>
 
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<%@ Register Src="~/ucFilterTree.ascx" TagName="ucFilterTree" TagPrefix="uc1" %>
 
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <telerik:RadSplitter ID="RadSplitter1" runat="server">
        <telerik:RadPane ID="rpLeft" runat="server">
            <uc1:ucFilterTree ID="ucFilterTreeLeft" runat="server" />
        </telerik:RadPane>
        <telerik:RadSplitBar ID="rsbSplit" runat="server"></telerik:RadSplitBar>
        <telerik:RadPane ID="rpRight" runat="server">
            <uc1:ucFilterTree ID="ucFilterTreeRight" runat="server" />
        </telerik:RadPane>
    </telerik:RadSplitter>
</asp:Content>

UserControl:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="ucFilterTree.ascx.vb" Inherits="TestTreeViewFiltering.ucFilterTree" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
 
<asp:UpdatePanel ID="upFilterTree" runat="server">
    <ContentTemplate>
        <telerik:RadTextBox ID="rtbFilterText" runat="server">
            <ClientEvents OnLoad="clientLoad" />
        </telerik:RadTextBox>
 
        <telerik:RadTreeView ID="rtvFilterTree" runat="server"></telerik:RadTreeView>
    </ContentTemplate>
</asp:UpdatePanel>
 
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
        <script type="text/javascript">
            String.prototype.startsWith = function (string) {
                return (this.lastIndexOf(string, 0) === 0);
            }
 
            var _timer = null;
 
            function clientLoad(sender) {
                $telerik.$(".riTextBox", sender.get_element().parentNode).bind("keydown", valueChanging);
            }
 
            function valueChanging(sender, args) {
                if (_timer) {
                    clearTimeout(_timer);
                }
 
                _timer = setTimeout(function () {
                    var _tree = $find("<%= rtvFilterTree.ClientID%>");
                    var _textBox = $find("<%= rtbFilterText.ClientID%>");
 
                    var _searchString = _textBox.get_element().value;
 
                    for (var _ii = 0; _ii < _tree.get_nodes().get_count() ; _ii++) {
                        findNodes(_tree.get_nodes().getNode(_ii), _searchString);
                    }
                }, 100);
            }
 
            function findNodes(node, searchString) {
                node.set_expanded(true);
 
                var _hasChildren = false;
 
                for (var _ii = 0; _ii < node.get_nodes().get_count() ; _ii++) {
                    _hasChildren = findNodes(node.get_nodes().getNode(_ii), searchString) || _hasChildren;
                }
 
                var _textToCheck = node.get_textElement().textContent;
                if (_hasChildren || _textToCheck.toLowerCase().startsWith(searchString.toLowerCase())) {
                    node.set_visible(true);
                    return true;
                } else {
                    node.set_visible(false);
                    return false;
                }
            }
        </script>
    </telerik:RadScriptBlock>

VB

Public Class ucFilterTree
    Inherits System.Web.UI.UserControl
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            rtvFilterTree.LoadContentFile("~/TreeData.xml")
        End If
    End Sub
 
End Class

XML Data:

<?xml version="1.0" encoding="utf-8" ?>
<Tree>
    <Node Text="Desktop" ToolTip="Desktop">
        <Node Text="Administrator">
            <Node Text="AppData" >
                <Node Text="Microsoft" />
            </Node>
            <Node Text="Contacts" />
            <Node Text="Downloads" />
            <Node Text="Documents" />
            <Node Text="Favorites" >
                <Node Text="Links" />
            </Node>
            <Node Text="Music" />
            <Node Text="Pictures" />
            <Node Text="Saved Games" />
            <Node Text="Searches" >
                <Node Text="History" />
            </Node>
            <Node Text="Videos" />
        </Node>
        <Node Text="Computer" ToolTip="My Computer">
            <Node Text="WebServer (\\10.0.0.80) (W:)" />
            <Node Text="Local Disk (C:)">
                <Node Text="inetpub">
                    <Node Text="AdminScripts"></Node>
                </Node>
            </Node>
            <Node Text="Local Disk (D:)">
                <Node Text="Movies" />
                <Node Text="Music" />
                <Node Text="Games" />
            </Node>
        </Node>
    </Node>
</Tree>

Thanks 

Dale

3 Answers, 1 is accepted

Sort by
0
Boyan Dimitrov
Telerik team
answered on 12 Aug 2013, 11:25 AM
Hello Dale,

I am glad to clarify that since RadControls Q1 2013 we have introduced the RadDropDownTree control that offers very similar functionality out of the box. That way you can achieve filtering functionality without using a client-side code. Pleas review the the RadDropDownTree online demos here for reference.

Regarding the issue with the provided code:
I am afraid that there is a problem with the retrieving of the associated RadTreeView client-side object. Please use the following workaround in order to solve that problem and filter the correct RadTreeView object.
//JavaScript
<asp:UpdatePanel ID="upFilterTree" runat="server">
    <ContentTemplate>
        <telerik:RadTextBox ID="rtbFilterText" runat="server">
            <ClientEvents OnLoad="clientLoad" />
        </telerik:RadTextBox>
  
        <telerik:RadTreeView ID="rtvFilterTree" runat="server"></telerik:RadTreeView>
    </ContentTemplate>
</asp:UpdatePanel>
  
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
        <script type="text/javascript">
            String.prototype.startsWith = function (string) {
                return (this.lastIndexOf(string, 0) === 0);
            }
 
            var _timer = null;
 
            function clientLoad(sender) {
                $telerik.$(sender.get_element()).bind("keydown", function () {
                    var _tree = $find($telerik.$(sender.get_element().parentNode.parentNode).find("div.RadTreeView")[0].id);
                     
 
                    var _searchString = sender.get_element().value;
 
                    for (var _ii = 0; _ii < _tree.get_nodes().get_count() ; _ii++) {
                        findNodes(_tree.get_nodes().getNode(_ii), _searchString);
                    }
 
                    
                });
            }
 
             
 
            function findNodes(node, searchString) {
                node.set_expanded(true);
 
                var _hasChildren = false;
 
                for (var _ii = 0; _ii < node.get_nodes().get_count() ; _ii++) {
                    _hasChildren = findNodes(node.get_nodes().getNode(_ii), searchString) || _hasChildren;
                }
 
                var _textToCheck = node.get_textElement().textContent;
                if (_hasChildren || _textToCheck.toLowerCase().startsWith(searchString.toLowerCase())) {
                    node.set_visible(true);
                    return true;
                } else {
                    node.set_visible(false);
                    return false;
                }
            }
        </script>
    </telerik:RadScriptBlock>


Regards,
Boyan Dimitrov
Telerik
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 the blog feed now.
0
Steve
Top achievements
Rank 1
answered on 13 Aug 2013, 09:25 AM
Hi Boyan

Thanks for the reply.

With regards to the change you suggested this does pick up the correct tree control, but doesn't apply the filter on KeyDown like the functionality in RadDropDownTree.  

If you put an alert(_searchString); after the line which gets the value from the sender.get_element().value; you can seen that while the tree does expand the nodes on first keydown event nothing is actually found in the textbox and therefore no filter applied.

If you TAB off the field then the filter is applied, or if you type another letter then the first letter is then applied.

Is there a way to get this to work on the first initial keydown event and then subsequent ones?


With regards to the RadDropDownTree, yes I had seen that functionality and this is what I was trying to replicate.  Is there a way to use the RadDropDownTree control ans to show the Filter box and Tree control, but completely hide the DropDown part, and also have is expaned at all times?

If there is then this would be the perfect option for me.

Thanks

Dale
0
Accepted
Boyan Dimitrov
Telerik team
answered on 16 Aug 2013, 10:36 AM
Hello Dale,

Yes indeed you can achieve such functionality by using a few lines of css code in order to hide the RadDropDownTree entry area and some JavaScript to avoid closing the drop down list. Please find attached a sample project attached illustrating the aforementioned approach.


Regards,
Boyan Dimitrov
Telerik
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 the blog feed now.
Tags
TreeView
Asked by
Steve
Top achievements
Rank 1
Answers by
Boyan Dimitrov
Telerik team
Steve
Top achievements
Rank 1
Share this question
or