commit extjs-2.2.1
[extjs.git] / source / widgets / tree / TreeFilter.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /**\r
10 * @class Ext.tree.TreeFilter\r
11 * Note this class is experimental and doesn't update the indent (lines) or expand collapse icons of the nodes\r
12 * @param {TreePanel} tree\r
13 * @param {Object} config (optional)\r
14  */\r
15 Ext.tree.TreeFilter = function(tree, config){\r
16     this.tree = tree;\r
17     this.filtered = {};\r
18     Ext.apply(this, config);\r
19 };\r
20 \r
21 Ext.tree.TreeFilter.prototype = {\r
22     clearBlank:false,\r
23     reverse:false,\r
24     autoClear:false,\r
25     remove:false,\r
26 \r
27      /**\r
28      * Filter the data by a specific attribute.\r
29      * @param {String/RegExp} value Either string that the attribute value \r
30      * should start with or a RegExp to test against the attribute\r
31      * @param {String} attr (optional) The attribute passed in your node's attributes collection. Defaults to "text".\r
32      * @param {TreeNode} startNode (optional) The node to start the filter at.\r
33      */\r
34     filter : function(value, attr, startNode){\r
35         attr = attr || "text";\r
36         var f;\r
37         if(typeof value == "string"){\r
38             var vlen = value.length;\r
39             // auto clear empty filter\r
40             if(vlen == 0 && this.clearBlank){\r
41                 this.clear();\r
42                 return;\r
43             }\r
44             value = value.toLowerCase();\r
45             f = function(n){\r
46                 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;\r
47             };\r
48         }else if(value.exec){ // regex?\r
49             f = function(n){\r
50                 return value.test(n.attributes[attr]);\r
51             };\r
52         }else{\r
53             throw 'Illegal filter type, must be string or regex';\r
54         }\r
55         this.filterBy(f, null, startNode);\r
56         },\r
57     \r
58     /**\r
59      * Filter by a function. The passed function will be called with each \r
60      * node in the tree (or from the startNode). If the function returns true, the node is kept \r
61      * otherwise it is filtered. If a node is filtered, its children are also filtered.\r
62      * @param {Function} fn The filter function\r
63      * @param {Object} scope (optional) The scope of the function (defaults to the current node) \r
64      */\r
65     filterBy : function(fn, scope, startNode){\r
66         startNode = startNode || this.tree.root;\r
67         if(this.autoClear){\r
68             this.clear();\r
69         }\r
70         var af = this.filtered, rv = this.reverse;\r
71         var f = function(n){\r
72             if(n == startNode){\r
73                 return true;\r
74             }\r
75             if(af[n.id]){\r
76                 return false;\r
77             }\r
78             var m = fn.call(scope || n, n);\r
79             if(!m || rv){\r
80                 af[n.id] = n;\r
81                 n.ui.hide();\r
82                 return false;\r
83             }\r
84             return true;\r
85         };\r
86         startNode.cascade(f);\r
87         if(this.remove){\r
88            for(var id in af){\r
89                if(typeof id != "function"){\r
90                    var n = af[id];\r
91                    if(n && n.parentNode){\r
92                        n.parentNode.removeChild(n);\r
93                    }\r
94                }\r
95            } \r
96         }\r
97     },\r
98     \r
99     /**\r
100      * Clears the current filter. Note: with the "remove" option\r
101      * set a filter cannot be cleared.\r
102      */\r
103     clear : function(){\r
104         var t = this.tree;\r
105         var af = this.filtered;\r
106         for(var id in af){\r
107             if(typeof id != "function"){\r
108                 var n = af[id];\r
109                 if(n){\r
110                     n.ui.show();\r
111                 }\r
112             }\r
113         }\r
114         this.filtered = {}; \r
115     }\r
116 };\r