Filter Tree as User Control, Javascript Issues

4 posts, 1 answers
  1. Dale
    Dale avatar
    11 posts
    Member since:
    Aug 2012

    Posted 07 Aug 2013 Link to this post

    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
  2. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 12 Aug 2013 Link to this post

    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.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Dale
    Dale avatar
    11 posts
    Member since:
    Aug 2012

    Posted 13 Aug 2013 Link to this post

    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
  5. Answer
    Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 16 Aug 2013 Link to this post

    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.
Back to Top