Javascript 带突出显示的剑道树视图搜索

Javascript 带突出显示的剑道树视图搜索,javascript,jquery,kendo-ui,kendo-treeview,Javascript,Jquery,Kendo Ui,Kendo Treeview,我有一个带spriteclass的KendoTreeview。我想用我的搜索词突出显示节点(根节点和子节点)。我已经实现了搜索功能。但是,当我搜索时,问题是突出显示节点中的术语,但在第一次搜索后节点中缺少SpriteClass。有什么想法吗 $('#搜索词')。在('keyup',函数(){ $('span.k-in>span.highlight')。每个(函数(){ $(this.parent().text($(this.parent().text()); }); //如果没有搜索词,则忽略

我有一个带spriteclass的KendoTreeview。我想用我的搜索词突出显示节点(根节点和子节点)。我已经实现了搜索功能。但是,当我搜索时,问题是突出显示节点中的术语,但在第一次搜索后节点中缺少SpriteClass。有什么想法吗

$('#搜索词')。在('keyup',函数(){
$('span.k-in>span.highlight')。每个(函数(){
$(this.parent().text($(this.parent().text());
});
//如果没有搜索词,则忽略
if($.trim($(this.val())=''){
返回;
}
var term=this.value.toUpperCase();
var tlen=期限长度;
$('#treeview精灵span.k-in')。每个(函数(索引){
var text=$(this.text();
var html='';
var q=0;
而((p=text.toUpperCase().indexOf(term,q))>=0){
html++=text.substring(q,p)+''+text.substr(p,tlen)+'';
q=p+tlen;
}
如果(q>0){
html+=text.substring(q);
$(this).html(html);
$(this).parentsUntil('.k-treeview').filter('.k-item')。每个(
函数(索引、元素){
$('#treeview精灵')。数据('kendoTreeView')。展开($(此));
$(此).data('search-term',term);
});
}
});
$(“#树视图精灵”).kendoTreeView({
数据源:[{
文本:“我的文件”,
对,,
精灵类:“根文件夹”,
项目:[{
文本:“剑道UI项目”,
对,,
精灵类:“文件夹”,
项目:[{
文本:“about.html”,
精灵类:“html”
}, {
文本:“index.html”,
精灵类:“html”
}, {
文本:“logo.png”,
精灵类:“图像”
}]
}, {
文字:“新网站”,
对,,
精灵类:“文件夹”,
项目:[{
文本:“mockup.jpg”,
精灵类:“图像”
}, {
正文:“Research.pdf”,
精灵类:“pdf”
}, ]
}, {
文本:“报告”,
对,,
精灵类:“文件夹”,
项目:[{
正文:“二月.pdf”,
精灵类:“pdf”
}, {
正文:“March.pdf”,
精灵类:“pdf”
}, {
正文:“April.pdf”,
精灵类:“pdf”
}]
}]
}]
})

如果你在它的HTML中乱涂乱画,剑道的树视图小部件不喜欢它,所以我建议改为修改数据源(这将需要DS中所有项目的
编码的
选项)

在keyup处理程序中,您可以在搜索时重置DS以清除突出显示,然后设置模型的文本属性,而不是直接替换元素的HTML:

$('#search-term').on('keyup', function () {
    var treeView = $("#treeview-sprites").getKendoTreeView();
    treeView.dataSource.data(pristine);

    // ignore if no search term
    if ($.trim($(this).val()) == '') {
        return;
    }

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

    $('#treeview-sprites span.k-in').each(function (index) {
        var text = $(this).text();
        var html = '';
        var q = 0;
        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);

            var dataItem = treeView.dataItem($(this));
            dataItem.set("text", html);

            $(this).parentsUntil('.k-treeview').filter('.k-item').each(

            function (index, element) {
                $('#treeview-sprites').data('kendoTreeView').expand($(this));
                $(this).data('search-term', term);
            });
        }
    });

    $('#treeview-sprites .k-item').each(function () {
        if ($(this).data('search-term') != term) {
            $('#treeview-sprites').data('kendoTreeView').collapse($(this));
        }
    });
});

()

干得好,伙计们,正是我所需要的

使用您的代码,我做了一个小小的调整(实际上只添加了两行jquery筛选),这样现在在搜索关键字时,树视图只显示包含高亮显示文本的分支。Easy peasy!:)

如果其他分支不包含高亮显示的文本,它们将被隐藏

这意味着我们现在有了类似VisualStudio的treeview搜索(请参阅VisualStudio解决方案浏览器搜索和筛选:)

以下是我在JSFIDLE上的代码和演示:

HTML:

<input id="treeViewSearchInput"></input>
<ul id="treeview">
    <li data-expanded="true">My Web Site
        <ul>
            <li data-expanded="true">images
                <ul>
                    <li>logo.png</li>
                    <li>body-back.png</li>
                    <li>my-photo.jpg</li>
                </ul>
            </li>
            <li data-expanded="true">resources
                <ul>
                    <li data-expanded="true">pdf
                        <ul>
                            <li>brochure.pdf</li>
                            <li>prices.pdf</li>
                        </ul>
                    </li>
                    <li>zip</li>
                </ul>
            </li>
            <li>about.html</li>
            <li>contacts.html</li>
            <li>index.html</li>
            <li>portfolio.html</li>
        </ul>
    </li>
    <li>Another Root</li>
</ul>
JAVASCRIPT

function InitSearch(treeViewId, searchInputId) {

    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()) === '') {
            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();

        $(treeViewId + ' li.k-item').expand(".k-item");
    });
}

var $tv = $("#treeview").kendoTreeView();

InitSearch("#treeview", "#treeViewSearchInput");
函数InitSearch(treeViewId、searchInputId){
var tv=$(treeViewId).data('kendoTreeView');
$(searchInput).on('keyup',函数(){
$(treeViewId+'li.k-item').show();
$('span.k-in>span.highlight')。每个(函数(){
$(this.parent().text($(this.parent().text());
});
//如果没有搜索词,则忽略
if($.trim($(this.val())=''){
返回;
}
var term=this.value.toUpperCase();
var tlen=期限长度;
$(treeViewId+'span.k-in')。每个(函数(索引){
var text=$(this.text();
var html='';
var q=0;
var-p;
而((p=text.toUpperCase().indexOf(term,q))>=0){
html++=text.substring(q,p)+''+text.substr(p,tlen)+'';
q=p+tlen;
}
如果(q>0){
html+=text.substring(q);
$(this).html(html);
$(this).parentsUntil('.k-treeview').filter('.k-item')。每个(函数(索引,元素){
扩大($(本));
$(此).data('SearchTerm',term);
});
}
});
$(treeViewId+'li.k-item:not(:has(“.highlight”))).hide();
$(treeViewId+li.k-item')。展开(“.k-item”);
});
}
var$tv=$(“#树视图”).kendoTreeView();
InitSearch(“treeview”,即“treeViewSearchInput”);
我又做了一个调整:)

我所做的是更改突出显示代码,以保留节点html中可能存在的任何其他内容(例如sprite span)

我还将其实现为树视图周围的TypeScript类包装器

如果您不需要TypeScript之类的东西,只需将代码复制出来,它就可以正常工作:)

导出类SearchableTreeView{
TreeView:kendo.ui.TreeView;
重点类:字符串;
构造函数(treeView:kendo.ui.treeView){
this.TreeView=TreeView;
this.emphasisClass=“bg警告”;
}
搜索(术语:字符串):无效{
var treeElement:JQuery=this.TreeView.element;
var-tv:kendo.ui.TreeView=this.TreeView;
var emphClass=此。emphasisClass;
这个.resetHighlights();
//如果没有搜索词,则忽略
如果($.tri
<input id="treeViewSearchInput"></input>
<ul id="treeview">
    <li data-expanded="true">My Web Site
        <ul>
            <li data-expanded="true">images
                <ul>
                    <li>logo.png</li>
                    <li>body-back.png</li>
                    <li>my-photo.jpg</li>
                </ul>
            </li>
            <li data-expanded="true">resources
                <ul>
                    <li data-expanded="true">pdf
                        <ul>
                            <li>brochure.pdf</li>
                            <li>prices.pdf</li>
                        </ul>
                    </li>
                    <li>zip</li>
                </ul>
            </li>
            <li>about.html</li>
            <li>contacts.html</li>
            <li>index.html</li>
            <li>portfolio.html</li>
        </ul>
    </li>
    <li>Another Root</li>
</ul>
span.k-in > span.highlight {
    background: #7EA700;
    color: #ffffff;
    border: 1px solid green;
    padding: 1px;
}
function InitSearch(treeViewId, searchInputId) {

    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()) === '') {
            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();

        $(treeViewId + ' li.k-item').expand(".k-item");
    });
}

var $tv = $("#treeview").kendoTreeView();

InitSearch("#treeview", "#treeViewSearchInput");
export class SearchableTreeView {
    TreeView: kendo.ui.TreeView;
    emphasisClass: string;

    constructor(treeView: kendo.ui.TreeView) {
        this.TreeView = treeView;
        this.emphasisClass = "bg-warning";
    }

    search(term: string): void {
        var treeElement: JQuery = this.TreeView.element;
        var tv: kendo.ui.TreeView = this.TreeView;
        var emphClass = this.emphasisClass;

        this.resetHighlights();

        // ignore if no search term
        if ($.trim(term) === '') { return; }

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

        $('span.k-in', treeElement).each(function (index) {
            // find all corresponding nodes
            var node = $(this);
            var htmlContent = node.html();
            var text = node.text();

            var searchPosition = text.toUpperCase().indexOf(term);
            if (searchPosition === -1) {
                // continue
                return true;
            }

            var generatedHtml = '<span class="highlight-container">' + text.substr(0, searchPosition) + '<span class="' + emphClass + '">' + text.substr(searchPosition, tlen) + '</span>' + text.substr(searchPosition + tlen) + '</span>';

            htmlContent = htmlContent.replace(text, generatedHtml);
            node.html(htmlContent);

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

        });

        $('.k-item', treeElement).each(function () {
            if ($(this).data('search-term') != term) {
                tv.collapse($(this));
            }
        });
    }

    resetHighlights(): void {
        this.TreeView.element.find("span.k-in:has('." + this.emphasisClass + "')")
            .each(function () {
                var node = $(this);
                var text = node.text();
                $(".highlight-container", node).remove();
                node.append(text);
            });
    }
}
   $("#textBox").on("input", function () {

    var query = this.value.toLowerCase();
    var dataSource = $("#Treeview").data("kendoTreeView").dataSource;

    filter(dataSource, query);
   });


  function filter(dataSource, query) {
        var uidData = [];
        var data = dataSource instanceof kendo.data.DataSource && dataSource.data();
        for (var i = 0; i < data.length; i++) {
            var item = data[i];
            var text = item.text.toLowerCase();
            var isChecked = item.checked;
            var itemVisible =
                query === true 
                || query === "" 
                || text.indexOf(query) >= 0; 

            uidData.push({ UID: item.uid, Visible: itemVisible });

        }

        if (query != "") {
            $.each(uidData, function (index, datavalue) {
                if (datavalue.Visible) {
                    $("li[data-uid='" + datavalue.UID + "']").addClass("highlight");
                }
                else {
                    $("li[data-uid='" + datavalue.UID + "']").removeClass("highlight");
                }

            });
        }
        else {
            $.each(uidData, function (index, datavalue) {
                $("li[data-uid='" + datavalue.UID + "']").removeClass("highlight");

            });
        }
    }
.highlight {
    background:#0fa1ba;
    color:white;
}
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { NGXLogger } from 'ngx-logger';

@Pipe({
    name: 'highlight'
})

export class TypeaheadHighlight implements PipeTransform {
    constructor(private readonly _sanitizer: DomSanitizer, private readonly logger: NGXLogger) { }
    transform(matchItem: any, query: any): string {
        let matchedItem: any;
        if (matchItem) {
            matchedItem = matchItem.toString();
        }
        if (this.containsHtml(matchedItem)) {
            this.logger.warn('Unsafe use of typeahead please use ngSanitize');
        }
        matchedItem = query ? ('' + matchedItem).replace(new RegExp(this.escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchedItem; // Replaces the capture string with a the same string inside of a "strong" tag

        if (!this._sanitizer) {
            matchedItem = this._sanitizer.bypassSecurityTrustHtml(matchedItem);
        }

        return matchedItem;
    }

    escapeRegexp = (queryToEscape) => queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');

    containsHtml = (matchItem) => /<.*>/g.test(matchItem);

} 
            <input name="searchTerm" type="text" [(ngModel)]="searchTerm" (keyup)='onkeyup(searchTerm)'
             />
        </div>

        <div style="height: 70vh;overflow: auto">
            <kendo-treeview style="margin-top: 50px" id="availableColumns" [nodes]="availableColumns"
                textField="displayName" kendoTreeViewExpandable kendoTreeViewFlatDataBinding idField="id"
                parentIdField="parentId">
                <ng-template kendoTreeViewNodeTemplate let-dataItem>
                    <span [tooltip]="dataItem.columnDescription"
                        [innerHtml]="dataItem.displayName | highlight:searchTerm "></span>
                </ng-template>
            </kendo-treeview>
        </div>