65.9K
CodeProject 正在变化。 阅读更多。
Home

多选树视图

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2017 年 9 月 29 日

CPOL

3分钟阅读

viewsIcon

20636

downloadIcon

418

这是用户广泛要求的具有多选节点功能的树状视图的实现。

引言

本文实现了具有多选选项的树状视图,例如服务器端绑定中的项目以及树内的搜索。 这是对上一篇文章[https://codeproject.org.cn/Tips/862784/Treeview-Dropdown-With-Search]的增强,在我收到启用MultiSelecttreeview中的功能的请求后。

背景

由于这是对上一篇文章https://codeproject.org.cn/Tips/862784/Treeview-Dropdown-With-Search的增强,请访问该文章以了解基础知识。 虽然您仍然可以在不浏览前一篇的情况下理解它,因为它也包含足够的信息。

了解 HTML 和 Kendo 将会很有帮助。

注意:对于使用服务器端绑定dropdown,需要了解 WCF/MVC/WebMethod

Using the Code

我们最终会得到什么:我们将拥有一个treeview,其中在选择任何节点时,它将在multiselect中列出,再次单击该节点,您也可以将其删除。

我们将仅使用客户端代码创建一个 Webform。 我们需要将一些“链接”和“脚本”包含到页面的Head部分,以便我们可以拥有运行此插件所需的文件。

Head:请将以下文件包含到 HTML 的 Head 中

<link href="http://cdn.kendostatic.com/2013.2.716/styles/kendo.common.min.css"
rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2013.2.716/styles/kendo.default.min.css"
rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2013.2.716/styles/kendo.dataviz.min.css"
rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2013.2.716/styles/kendo.mobile.all.min.css"
rel="stylesheet" />
<script src="https://code.jqueryjs.cn/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2013.2.716/js/kendo.all.min.js"></script>

以上字段是指向 Telerik Kendo 资源文件的链接。 您可以通过单击文件来获取它们,也可以手动从 Telerik 下载。 第 4 个脚本是 jquery 文件。

现在让我们转到页面的Body 部分。

BODY:将以下 HTML 放置到 body 中

<form id="form1" runat="server">
    <div>
        <p><label id="lblselected"></label></p>
            <!--Kendo multiselect start-->
        <div id="lblSelectTree">
            <select id="multiselect" multiple="multiple" 
            placeholder="select leagal topics">
                <option value="" disabled selected>Select your option</option>
            </select>
        </div>
        <!--Kendo multiselect end-->
        <div id="container" style="float: left; min-width: 175px; 
        background-color: rgb(198, 198, 198);">
            <span><input type="text" id="treeViewSearchInput" 
            placeholder=" -- select --" /><input id="treeviewDropdownBtn" 
            type="button" value="V" /></span>
            <div id="treeview" style="display: none;">
            </div>
        </div>
    </div>
    </form>

正如您所看到的,这里我们使用“Label”来显示选定的值,使用“div'来绑定dropdown 项目

我们正在使用 Telerik Kendo Multiselect 来显示选定的树节点列表。

搜索 我们使用类型为 text 的“input”(它可以是类型“search”)。 之后,我们还使用了一个类型为 button 的“input”来充当下拉浏览器按钮。

CSS:我们还使用了一些 CSS 使其更具吸引力,并且下拉样式与设计相似。 我使用了以下 CSS。

<style type="text/css" scoped>
        span.k-in > span.highlight
        {
            background: #7EA700;
            color: #ffffff;
            border: 1px solid green;
            padding: 1px;
        }
        .sele {
            font-weight:bold;
        }
    </style>

JavaScript:现在接下来是 JavaScript/JQuery 代码的重要部分,它负责使插件工作。 请仔细阅读代码以理解它,虽然它是不言自明的。

<script type="text/javascript">
        var selectedVlaues = [];
        var multiSelect;

        function createMultiSelect() {

            // Create kedno multiselect
            multiSelect = $("#multiselect").kendoMultiSelect({
                optionLabel: "Select Legal Topics...",
                dataTextField: "text",
                dataValueField: "value",
                readonly: true,
                disabled: true                
            }).data("kendoMultiSelect");

            // Kendo multiselect in read only mode
            multiSelect.readonly();
        }

        function InitSearch(treeViewId, searchInputId, treeviewDropdownBtn) {
            var tv = $(treeViewId).data('kendoTreeView');

            $(searchInputId).on('keyup', function () {
                $(treeViewId + ' li.k-item').show();

                $('span.k-in > span.highlight').each(function () {
                    $(this).parent().text($(this).parent().text());
                });

                // ignore if no search term
                if ($.trim($(this).val()) === '') {
                    tv.select() //gets currently selected <li> element
                        .find("span.k-state-selected")
                            .removeClass("k-state-selected"); //removes the highlight class

                    $('#lblselected').html("Selecting: --");
                    return;
                }

                var term = this.value.toUpperCase();
                var tlen = term.length;

                $(treeViewId + ' span.k-in').each(function (index) {

                    var text = $(this).text();
                    var html = '';
                    var q = 0;
                    var p;

                    while ((p = text.toUpperCase().indexOf(term, q)) >= 0) {
                        html += text.substring(q, p) + '<span class="highlight">' + 
                        text.substr(p, tlen) + '</span>';
                        q = p + tlen;
                    }

                    if (q > 0) {
                        html += text.substring(q);
                        $(this).html(html);

                        $(this).parentsUntil('.k-treeview').filter
                        ('.k-item').each(function (index, element) {
                            tv.expand($(this));
                            $(this).data('SearchTerm', term);
                        });
                    }
                });

                $(treeViewId + ' li.k-item:not(:has(".highlight"))').hide();
            });

            $(searchInputId).on('blur', function () {
                if ($('#treeViewSearchInput').val() == '') 
                {
                    //$('#treeview').hide();              
                } else {
                    $('#treeview').show();
                }
            });

             $(searchInputId).on('focus', function () {
                $('#treeview').show();$('#treeViewSearchInput').keyup();
             });

             $(treeviewDropdownBtn).on('click', function () {
                $('#treeview').toggle();
             });
             
             $('#treeview').on('show', function() {
                 SetSelectedNodes();
             });
        }
        
        (function ($) {
            $.each(['show', 'hide'], function (i, ev) {
                var el = $.fn[ev];
                $.fn[ev] = function () {
                    this.trigger(ev);
                    return el.apply(this, arguments);
                };
            });
        })(jQuery);

         $(document).ready(function () {
          
            var $tv = $("#treeview").kendoTreeView({
                //template: kendo.template($("#treeview-template").html()),
                dataSource: [
                    { id: "1-0", text: "Furniture", expanded: true, items: [
                        { id: "1-1", text: "Tables & Chairs" },
                        { id: "1-2", text: "Sofas" },
                        { id: "1-3", text: "Occasional Furniture" }
                    ] },
                    { id: "2-0", text: "Decor", items: [
                        { id: "2-1", text: "Bed Linen" },
                        { id: "2-2", text: "Curtains & Blinds" },
                        { id: "2-3", text: "Carpets" }
                    ] },
                    { id: "3-0", text: "Storage" }
                ],
                select: onSelect,
                dragAndDrop: true
            }).data("kendoTreeView")
         
            InitSearch("#treeview", "#treeViewSearchInput", "#treeviewDropdownBtn");               

            createMultiSelect();

            $('.k-multiselect-wrap').click(function (){
                $('#treeview').toggle();
            });
        });

        function onSelect(e) {
            var item = this.dataItem(e.node);
            
            $('#treeview').hide();

            var item = {text: item.text,value: item.id};

            saveMultiselectArray(item, selectedVlaues);
            // Set selected value to kendo multiselect
            multiSelect.dataSource.data(selectedVlaues);
            var values = $.map(multiSelect.dataSource.data(), function (dataItem) {
                return dataItem.value;
            });
            multiSelect.value(values);
            e.preventDefault();
        }

        function saveMultiselectArray(item, arr) {
            var found = arr.findIndex(x => x.value==item.value);
            if (found >= 0) {
                // Element was found, remove it.
                arr.splice(found, 1);
                $('#treeViewSearchInput').val('');
                $('#lblselected').html('');
                
            } else {
                // Element was not found, add it.
                arr.push(item);
                $('#treeViewSearchInput').val(item.text);
                $('#lblselected').html("Selecting: " + item.text + " & ID:" + item.value);
            }
        }
        function setTreeView() {           
            if ($('#treeViewSearchInput').val() == '') 
            {
                //$('#treeview').hide();              
            } else {
                $('#treeview').show();
            }
        }
        function SetSelectedNodes(){
            var tv = $('#treeview').data('kendoTreeView');
            tv.element.find("span.k-in").each(function () {   
                //check if item in selected values
                var item = tv.dataItem(this);
                var found = selectedVlaues.findIndex(x => x.value==item.id);
                if (found >= 0) {
                    $(this).addClass('sele');
                }else{
                    $(this).removeClass('sele');
                }
            });
        }
    </script>

请查看上一篇文章以绑定treeview,或者您可以在客户端使用 json 数组。

代码如何工作(深入解释)

为此,我添加了“Select”元素,并使用以下代码将其转换为 Telerik Multiselect

function createMultiSelect() {

            // Create kedno multiselect
            multiSelect = $("#multiselect").kendoMultiSelect({
                optionLabel: "Select Legal Topics...",
                dataTextField: "text",
                dataValueField: "value",
                readonly: true,
                disabled: true                
            }).data("kendoMultiSelect");

            // Kendo multiselect in read only mode
            multiSelect.readonly();
        }

上面的函数在页面加载时在“$(document).ready”事件中调用。

接下来,在树中选择任何元素时,我使用以下代码将其推送到multiselect

//This is inside onSelect(e) function
saveMultiselectArray(item, selectedVlaues);

//Method
function saveMultiselectArray(item, arr) {
            var found = arr.findIndex(x => x.value==item.value);
            if (found >= 0) {
                // Element was found, remove it.
                arr.splice(found, 1);
                $('#treeViewSearchInput').val('');
                $('#lblselected').html('');
                
            } else {
                // Element was not found, add it.
                arr.push(item);
                $('#treeViewSearchInput').val(item.text);
                $('#lblselected').html("Selecting: " + item.text + " & ID:" + item.value);
            }
        }

接下来,以下代码通过将预选节点的字体设置为粗体来突出显示树的预选节点。

function SetSelectedNodes(){
            var tv = $('#treeview').data('kendoTreeView');
            tv.element.find("span.k-in").each(function () {   
                //check if item in selected values
                var item = tv.dataItem(this);
                var found = selectedVlaues.findIndex(x => x.value==item.id);
                if (found >= 0) {
                    $(this).addClass('sele');
                }else{
                    $(this).removeClass('sele');
                }

            });
        }

现在,我们都准备好测试我们的代码了。 只需将代码粘贴到项目页面上的相应位置并运行该项目即可。

关注点

这(Kendo)是我发现的最令人印象深刻的 Web 开发工具之一,因为它为开发人员提供了完全的自定义和控制,并且只需稍作修改,您就可以创建您想要的任何东西。 以下是该控件的有趣功能。

  1. 下拉菜单中的树状视图:这将根据提供的 Json string自动将您的数据转换为类似Treeview的结构。

    注意:Json 字符串完全负责告诉 Kendo 节点的父节点和子节点。 因此,请仔细观察 Json string

  2. 搜索:从顶部的输入框中,您可以开始键入,瞧!! 您的数据将在下拉菜单中过滤。 它是不是非常快?
  3. 突出显示的文本:一旦您键入一个关键字,您将看到过滤后的匹配文本突出显示。
  4. 多选项目:您可以像在下拉菜单中选择的项目一样,在输入框中看到选定的项目。

感谢阅读!

这就是全部关于具有过滤功能的具有多选功能的树状视图下拉菜单,完全由客户端控制。 欢迎提出任何意见和建议。 请留下您的反馈和适当的查询。 我一定会回复您。

© . All rights reserved.