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