FilteredListBox - Client-side RadListBox Filter

Thread is closed for posting
10 posts, 1 answers
  1. 1B52FB95-E42A-40E4-88A4-8B7BC7724C74
    1B52FB95-E42A-40E4-88A4-8B7BC7724C74 avatar
    43 posts
    Member since:
    Nov 2009

    Posted 07 Oct 2011 Link to this post

    Requirements

    RadControls version  2011.2.915.40
    .NET version  4.0
    Visual Studio version  2010
    programming language  C#
    browser support  

    all browsers supported by RadControls


    PROJECT DESCRIPTION
    This is an updated version of the project I originally posted here.

    This project combines a RadTextBox with a RadListBox to filter the RadListBox items much like the RadComboBox filters its items.  A video demo can be seen here.

    To run the project, just extract FilteredListBox.zip, expand the FilteredListBox folder and double-click on  FilteredListBox.csproj.  It should open in Visual Studio and then just run it.  I've included the Telerik trial version dlls.

    Notes:

    Up and Down Arrow Usage: If the user uses the up and down arrows to go through a filtered list, it may appear to not work because the up and down arrow will potentially be "stopping" on hidden items.

    Clearing the Filter after a Transfer: I opted to clear the filtered list and the filter after a transfer is made.  Otherwise, if the user transfers the item back while your listbox is filtered, you'll need to re-filter.  Also, that item may not match the filter criteria and seem to disappear to the user.

    CSS:
    body
    {
        font-family: Trebuchet MS, Sans-Serif;
    }
             
    .listBoxHeaders
    {
        color:Green;
        font-weight:bold;
    }
             
    .RadListBox span.rlbText em
    {
        background-color: #E5E5E5;
        font-weight: bold;
        font-style: normal;
    }
             
    .rbClear
    {
        background-image: url(images/clear.png);
        background-position: center;
        background-repeat: no-repeat;
    }


    ASP.NET Markup:
    <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
    <Scripts>
        <%--Needed for JavaScript IntelliSense in VS2010--%>
        <%--For VS2008 replace RadScriptManager with ScriptManager--%>
        <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
        <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
        <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js" />
    </Scripts>
    </telerik:RadScriptManager>
    <telerik:RadCodeBlock runat="server" >
    <script type="text/javascript">
     
        function filterList()
        {
            var listbox = $find("<%= rlbAvailable.ClientID %>");
            var textbox = $find('<%= tbAvailableFilter.ClientID %>');
     
            clearListEmphasis(listbox);
            createMatchingList(listbox, textbox.get_textBoxValue());
        }
     
        // Remove emphasis from matching text in ListBox
        function clearListEmphasis(listbox)
        {
            var re = new RegExp("</{0,1}em>", "gi");
            var items = listbox.get_items();
            var itemText;
     
            items.forEach
            (
                function (item)
                {
                    itemText = item.get_text();
                    item.set_text(itemText.replace(re, ""));
                }
            )
        }
     
        // Emphasize matching text in ListBox and hide non-matching items
        function createMatchingList(listbox, filterText)
        {
            if (filterText != "")
            {
                filterText = escapeRegExCharacters(filterText);
     
                var items = listbox.get_items();
                var re = new RegExp(filterText, "i");
     
                items.forEach
                (
                    function (item)
                    {
                        var itemText = item.get_text();
     
                        if (itemText.match(re))
                        {
                            item.set_text(itemText.replace(re, "<em>" + itemText.match(re) + "</em>"));
                            item.set_visible(true);
                        }
                        else
                        {
                            item.set_visible(false);
                        }
                    }
                )
            }
            else
            {
                var items = listbox.get_items();
     
                items.forEach
                (
                    function (item)
                    {
                        item.set_visible(true);
                    }
                )  
            }
        }
     
        function rlbAvailable_OnClientTransferring(sender, eventArgs)
        {
            // Transferred items retain the emphasized text, so it needs to be cleared.
            clearListEmphasis(sender);
            // Clear the list. Optional, but prevents follow up situation.
            clearFilterText();
            createMatchingList(sender, "");
        }
     
        function rbtnClear_OnClientClicking(sender, eventArgs)
        {
            clearFilterText();
     
            var listbox = $find("<%= rlbAvailable.ClientID %>");
                     
            clearListEmphasis(listbox);
            createMatchingList(listbox, "");
        }
                 
        // Clears the text from the filter.
        function clearFilterText()
        {
            var textbox = $find('<%= tbAvailableFilter.ClientID %>');
            textbox.clear();
        }
     
        // Escapes RegEx character classes and shorthand characters
        function escapeRegExCharacters(text)
        {
            return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
        }
     
    </script>
    </telerik:RadCodeBlock>
    <div style="margin-bottom: 10px;">
    <telerik:RadButton ID="btnSave" runat="server"
        Text="Save"
        onclick="btnSave_Click">
        <Icon PrimaryIconCssClass="rbSave" />
    </telerik:RadButton>
    </div>
    <div class="listBoxHeaders">
        <span style="margin-left:50px;">
            Available States
        </span>
        <span style="margin-left:136px;">
            Chosen States
        </span>
    </div>
    <div>
        <table style="position:relative;left:-3px;margin-bottom:2px;">
            <tr>
                <td>
                    <telerik:RadTextBox ID="tbAvailableFilter" runat="server"
                        Width="187px"
                        EmptyMessage="Search States..."
                        autocomplete="off"
                        onkeyup="filterList();" />
                </td>
                <td>
                    <telerik:RadButton ID="rbtnClear" runat="server"
                        Width="22px"
                        AutoPostBack="false"
                        OnClientClicking="rbtnClear_OnClientClicking">
                        <Icon PrimaryIconCssClass="rbClear" />
                    </telerik:RadButton>
                </td>
            </tr>
        </table>
    </div>
    <telerik:RadListBox ID="rlbAvailable" runat="server"
        Height="250px"
        Width="250px"
        AllowTransfer="true"
        AllowTransferOnDoubleClick="true"
        TransferToID="rlbChosen"
        EnableDragAndDrop="true"
        OnClientTransferring="rlbAvailable_OnClientTransferring"
        ButtonSettings-ShowTransferAll="false"/>
    <telerik:RadListBox ID="rlbChosen" runat="server"
        Height="250px"
        Width="250px"
        EnableDragAndDrop="true"
        AllowReorder="true"/>
    <br /><br />
    <strong>States I've Lived In:</strong>
    <asp:Repeater ID="rptStates" runat="server">
        <ItemTemplate>
            <div><%# Eval("Text") %></div>
        </ItemTemplate>
    </asp:Repeater>

    C#
    using System;
     
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                rlbAvailable.LoadContentFile("states.xml");
            }
        }
     
        protected void btnSave_Click(object sender, EventArgs e)
        {
            rptStates.DataSource = rlbChosen.Items;
            rptStates.DataBind();
        }
     
    }
  2. Answer
    EBDE0ADD-8444-40B2-BC54-2D41F1A10160
    EBDE0ADD-8444-40B2-BC54-2D41F1A10160 avatar
    11 posts
    Member since:
    Apr 2010

    Posted 26 Apr 2013 Link to this post

    This is a brilliant idea; I'm going to use it.  I wish Telerik would support a RadComboBox Multi-select (Checkboxes) + Filter Contains functionality, but until then, this is a good solution.  In fact, I think Telerik should have this functionality included with their RadListBox.

    Thanks!
    Andre
  3. 192FB85E-58AB-4462-B4DF-85D99AAD4EAC
    192FB85E-58AB-4462-B4DF-85D99AAD4EAC avatar
    5 posts
    Member since:
    Dec 2013

    Posted 29 Jan 2014 in reply to 1B52FB95-E42A-40E4-88A4-8B7BC7724C74 Link to this post

    Hello Jon,

    I have tried implementing this, however within the filterList() function
    $find always returns null. I changed it to $.find and it gets past this now, but then in the clearListEmphasis function, I am getting a JS error
    on listbox.get_items()
    Error: Object doesn't support this property or method

    Any idea what I'm doing wrong?
  4. 26B6D8A3-7747-4BAC-83DF-B093F8126EA1
    26B6D8A3-7747-4BAC-83DF-B093F8126EA1 avatar
    2062 posts
    Member since:
    Dec 2019

    Posted 03 Feb 2014 Link to this post

    Hello,

    I would like to clarify that I run project and it works fine. Could you please confirm that you are facing the described problem without modifying the code? I have attached the project with latest trial version of our controls. Please try to run the project and let us know how that worked.


    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 UI for ASP.NET AJAX, subscribe to the blog feed now.
  5. 91BEE68D-C794-4115-A4A7-4E95F2B48C54
    91BEE68D-C794-4115-A4A7-4E95F2B48C54 avatar
    50 posts
    Member since:
    Jan 2006

    Posted 27 Oct 2015 Link to this post

    Hi,

    URL: http://telerik_test.ximnet.com.my/radlistbox_filter.aspx

    I tried the example but my listbox is using itemtemplate.
    After user search, other control in the item is destroyed and left with item name only.
    How can we solve this?

     

  6. FD4F2CE6-07D4-44AD-9B9D-F7D59CB3B5C3
    FD4F2CE6-07D4-44AD-9B9D-F7D59CB3B5C3 avatar
    1890 posts
    Member since:
    Apr 2022

    Posted 28 Oct 2015 Link to this post

    Hello,

    Тhe reason for the experienced issue in this custom scenario is the fact that the text of the items is altered in the createMatchingList function, by inserting em tags. Consider avoiding such modification of the text in  the items, in order to persist the proper behavior - remove
    item.set_text(itemText.replace(re, "<em>" + itemText.match(re) + "</em>")); in the createMatchingList  function.

    Regards,
    Nencho
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  7. AD6F09A1-4A47-4854-AE58-2E8DE5C21C6B
    AD6F09A1-4A47-4854-AE58-2E8DE5C21C6B avatar
    6 posts
    Member since:
    Apr 2013

    Posted 19 Apr 2016 Link to this post

    Hello There,

     

    I am using the given solution and it is working perfectly fine. But now a days I am facing one issue that if my list contains 5000 records and when I start typing in search text box, browser gets hanged. FF gives me scripting error and Chrome gives me no result and  it keeps on waiting.

     

    Please let me know, anybody faced such issue and what is the possible solution for this.

     

    Thanks
    Ashwin

  8. CF299DA3-9CD1-4784-A028-42B965388E4E
    CF299DA3-9CD1-4784-A028-42B965388E4E avatar
    18 posts
    Member since:
    Oct 2010

    Posted 11 Sep 2017 in reply to 1B52FB95-E42A-40E4-88A4-8B7BC7724C74 Link to this post

    Just one comment - If you add the item.enable() and item.disable() together with setting the visibility of the item, you will not have any problems with selecting items using arrows since disabled elements can't be selected.
  9. rishi mathur
    rishi mathur avatar
    4 posts
    Member since:
    Feb 2016

    Posted 14 Nov 2019 in reply to AD6F09A1-4A47-4854-AE58-2E8DE5C21C6B Link to this post

    Hi Ashwin

    I am facing exactly same issue. You got any solution for this? How can we optimize and improve the speed when we have large number to records. Can you please share the solution for this

  10. 73AB4FDB-9F60-4E95-94E8-05C89D609656
    73AB4FDB-9F60-4E95-94E8-05C89D609656 avatar
    912 posts
    Member since:
    Apr 2022

    Posted 19 Nov 2019 Link to this post

    Hello Rishi,

    The Client-side filtering loads all the items on the page, so on each filtering operation all items will be iterated. With that said, I am afraid that the only possible performance optimization is using the Load On Demand approach: 

    Regards,
    Peter Milchev
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top

This Code Library is part of the product documentation and subject to the respective product license agreement.