javascript - ExtJS -- 突出显示树 typeAhead 的匹配节点

标签 javascript extjs

我正在使用由 Sencha 的一名成员创建的树过滤器插件。这是他对插件的 fiddle :http://jsfiddle.net/slemmon/fSJwF/2/

正如您在 fiddle 中看到的那样,当 typeAhead 结果是父节点时,其所有子节点都会展开。因此,我想突出显示所有匹配结果,因为我经常会得到大量包含匹配 typeAhead 搜索词的父节点,并且它们有数百个子节点,因此很难找到匹配的父节点。

复制粘贴 fiddle 中的片段,因为 SO 抛出“指向 jsfiddle 的链接必须附有代码”错误...

filter: function (value, property, re) {
            var me = this
                , tree = me.tree
                , matches = []                                          // array of nodes matching the search criteria
                , root = tree.getRootNode()                                // root node of the tree
                , property = property || 'text'                          // property is optional - will be set to the 'text' propert of the  treeStore record by default
                , re = re || new RegExp(value, "ig")                     // the regExp could be modified to allow for case-sensitive, starts  with, etc.
                , visibleNodes = []                                      // array of nodes matching the search criteria + each parent non-leaf  node up to root
                , viewNode;

            if (Ext.isEmpty(value)) {                                    // if the search field is empty
                me.clearFilter();
                return;
            }

            tree.expandAll();                                            // expand all nodes for the the following iterative routines

            // iterate over all nodes in the tree in order to evalute them against the search criteria
            root.cascadeBy(function (node) {
                if (node.get(property).match(re)) {                         // if the node matches the search criteria and is a leaf (could be  modified to searh non-leaf nodes)
                    matches.push(node)                                  // add the node to the matches array
                }
            });

            if (me.allowParentFolders === false) {                         // if me.allowParentFolders is false (default) then remove any  non-leaf nodes from the regex match
                Ext.each(matches, function (match) {
                    if (!match.isLeaf()) { Ext.Array.remove(matches, match); }
                });
            }

            Ext.each(matches, function (item, i, arr) {                 // loop through all matching leaf nodes
                root.cascadeBy(function (node) {                         // find each parent node containing the node from the matches array
                    if (node.contains(item) == true) {
                        visibleNodes.push(node)                          // if it's an ancestor of the evaluated node add it to the visibleNodes  array
                    }
                });
                if (me.allowParentFolders === true &&  !item.isLeaf()) {    // if me.allowParentFolders is true and the item is  a non-leaf item
                    item.cascadeBy(function (node) {                    // iterate over its children and set them as visible
                        visibleNodes.push(node)
                    });
                }
                visibleNodes.push(item)                                  // also add the evaluated node itself to the visibleNodes array
            });

            root.cascadeBy(function (node) {                            // finally loop to hide/show each node
                viewNode = Ext.fly(tree.getView().getNode(node));       // get the dom element assocaited with each node
                if (viewNode) {                                          // the first one is undefined ? escape it with a conditional
                    viewNode.setVisibilityMode(Ext.Element.DISPLAY);     // set the visibility mode of the dom node to display (vs offsets)
                    viewNode.setVisible(Ext.Array.contains(visibleNodes, node));
                }
            });
        }

谢谢。

最佳答案

解决该问题的方法之一是将附加类附加到匹配的元素并按照您想要的方式设置其样式。

在下面的源代码中,我为每个匹配的项目添加了“matched”类。 fiddle 链接是 http://jsfiddle.net/0o0wtr7j/

Ext.define('TreeFilter', {
extend: 'Ext.AbstractPlugin'
    , alias: 'plugin.treefilter'

    , collapseOnClear: true                                             // collapse all nodes when clearing/resetting the filter
    , allowParentFolders: false                                         // allow nodes not designated as 'leaf' (and their child items) to  be matched by the filter

    , init: function (tree) {
        var me = this;
        me.tree = tree;

        tree.filter = Ext.Function.bind(me.filter, me);
        tree.clearFilter = Ext.Function.bind(me.clearFilter, me);
    }

    , filter: function (value, property, re) {
        var me = this
            , tree = me.tree
            , matches = []                                          // array of nodes matching the search criteria
            , root = tree.getRootNode()                                // root node of the tree
            , property = property || 'text'                          // property is optional - will be set to the 'text' propert of the  treeStore record by default
            , re = re || new RegExp(value, "ig")                     // the regExp could be modified to allow for case-sensitive, starts  with, etc.
            , visibleNodes = []                                      // array of nodes matching the search criteria + each parent non-leaf  node up to root
        , matchedClass = 'matched'
        , viewNode;

        if (Ext.isEmpty(value)) {                                    // if the search field is empty
            me.clearFilter();
            return;
        }

        tree.expandAll();                                            // expand all nodes for the the following iterative routines

        // iterate over all nodes in the tree in order to evalute them against the search criteria
        root.cascadeBy(function (node) {
            if (node.get(property).match(re)) {                         // if the node matches the search criteria and is a leaf (could be  modified to searh non-leaf nodes)
                node.set('cls', matchedClass);
                matches.push(node)                                  // add the node to the matches array
            } else {
                node.set('cls', '');
            }
        });

        if (me.allowParentFolders === false) {                         // if me.allowParentFolders is false (default) then remove any  non-leaf nodes from the regex match
            Ext.each(matches, function (match) {
                if (!match.isLeaf()) { Ext.Array.remove(matches, match); }
            });
        }

        Ext.each(matches, function (item, i, arr) {                 // loop through all matching leaf nodes
            root.cascadeBy(function (node) {                         // find each parent node containing the node from the matches array
                if (node.contains(item) == true) {
                    visibleNodes.push(node)                          // if it's an ancestor of the evaluated node add it to the visibleNodes  array
                }
            });
            if (me.allowParentFolders === true &&  !item.isLeaf()) {    // if me.allowParentFolders is true and the item is  a non-leaf item
                item.cascadeBy(function (node) {                    // iterate over its children and set them as visible
                    visibleNodes.push(node)
                });
            }
            visibleNodes.push(item)                                  // also add the evaluated node itself to the visibleNodes array
        });

        root.cascadeBy(function (node) {                            // finally loop to hide/show each node
            viewNode = Ext.fly(tree.getView().getNode(node));       // get the dom element assocaited with each node
            if (viewNode) {                                          // the first one is undefined ? escape it with a conditional
                viewNode.setVisibilityMode(Ext.Element.DISPLAY);     // set the visibility mode of the dom node to display (vs offsets)
                viewNode.setVisible(Ext.Array.contains(visibleNodes, node));
            }
        });
    }

    , clearFilter: function () {
        var me = this
            , tree = this.tree
            , root = tree.getRootNode();

        if (me.collapseOnClear) { tree.collapseAll(); }             // collapse the tree nodes
        root.cascadeBy(function (node) {                            // final loop to hide/show each node
            node.set('cls', '');
            viewNode = Ext.fly(tree.getView().getNode(node));       // get the dom element assocaited with each node
            if (viewNode) {                                          // the first one is undefined ? escape it with a conditional and show  all nodes
                viewNode.show();
            }
        });
    }});

关于javascript - ExtJS -- 突出显示树 typeAhead 的匹配节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28773721/

相关文章:

javascript - 如何只从没有列名和括号的对象数组中获取值?

javascript - 在 Javascript 中设置 Cookie 在值存在时返回未定义

javascript - Angular.js 仅在前端或后端处理数据

sencha-touch - 为什么我应该使用Ext.dispatch而不是直接调用 Controller 代码?

php - Ext Tree,数据显示在控制台,但不显示在页面上

javascript - 如何优雅地从 firebase 读取一个 >>new<< 项目?

javascript - knockoutjs - ko.mapping.fromJS 不工作

javascript - 使用电子表格 selModel 时,在哪里以编程方式设置列过滤器?

javascript - 匹配特殊字符,包括方括号

javascript - 在 Ext.tree.panel 的特定位置插入一个节点