Diffstat (limited to 'frontend/beta/js/YUI-extensions/tree/TreeFilter.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI-extensions/tree/TreeFilter.js | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/tree/TreeFilter.js b/frontend/beta/js/YUI-extensions/tree/TreeFilter.js new file mode 100644 index 0000000..9eeb274 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/tree/TreeFilter.js | |||
@@ -0,0 +1,105 @@ | |||
1 | /** | ||
2 | * This doesn't update the indent (lines) or expand collapse icons of the nodes | ||
3 | */ | ||
4 | YAHOO.ext.tree.TreeFilter = function(tree, config){ | ||
5 | this.tree = tree; | ||
6 | this.filtered = {}; | ||
7 | YAHOO.ext.util.Config.apply(this, config, { | ||
8 | clearBlank:false, | ||
9 | reverse:false, | ||
10 | autoClear:false, | ||
11 | remove:false | ||
12 | }); | ||
13 | }; | ||
14 | |||
15 | YAHOO.ext.tree.TreeFilter.prototype = { | ||
16 | /** | ||
17 | * Filter the data by a specific attribute. | ||
18 | * @param {String/RegExp} value Either string that the attribute value | ||
19 | * should start with or a RegExp to test against the attribute | ||
20 | * @param {String} attr (optional) The attribute passed in your node's attributes collection. Defaults to "text". | ||
21 | * @param {TreeNode} startNode (optional) The node to start the filter at. | ||
22 | */ | ||
23 | filter : function(value, attr, startNode){ | ||
24 | attr = attr || 'text'; | ||
25 | var f; | ||
26 | if(typeof value == 'string'){ | ||
27 | var vlen = value.length; | ||
28 | // auto clear empty filter | ||
29 | if(vlen == 0 && this.clearBlank){ | ||
30 | this.clearFilter(); | ||
31 | return; | ||
32 | } | ||
33 | value = value.toLowerCase(); | ||
34 | f = function(n){ | ||
35 | return n.attributes[attr].substr(0, vlen).toLowerCase() == value; | ||
36 | } | ||
37 | }else if(value.exec){ // regex? | ||
38 | f = function(n){ | ||
39 | return value.test(n.attributes[attr]); | ||
40 | } | ||
41 | }else{ | ||
42 | throw 'Illegal filter type, must be string or regex'; | ||
43 | } | ||
44 | this.filterBy(f, null, startNode); | ||
45 | }, | ||
46 | |||
47 | /** | ||
48 | * Filter by a function. The passed function will be called with each | ||
49 | * node in the tree (or from the startNode). If the function returns true, the node is kept | ||
50 | * otherwise it is filtered. If a node is filtered, it's children are also filtered. | ||
51 | * @param {Function} fn The filter function | ||
52 | * @param {Object} scope (optional) The scope of the function (defaults to the current node) | ||
53 | */ | ||
54 | filterBy : function(fn, scope, startNode){ | ||
55 | startNode = startNode || this.tree.root; | ||
56 | if(this.autoClear){ | ||
57 | this.clearFilter(); | ||
58 | } | ||
59 | var af = this.filtered, rv = this.reverse; | ||
60 | var f = function(n){ | ||
61 | if(n == startNode){ | ||
62 | return true; | ||
63 | } | ||
64 | if(af[n.id]){ | ||
65 | return false; | ||
66 | } | ||
67 | var m = fn.call(scope || n, n); | ||
68 | if(!m || rv){ | ||
69 | af[n.id] = n; | ||
70 | n.ui.hide(); | ||
71 | return false; | ||
72 | } | ||
73 | return true; | ||
74 | } | ||
75 | startNode.cascade(f); | ||
76 | if(this.remove){ | ||
77 | for(var id in af){ | ||
78 | if(typeof id != 'function'){ | ||
79 | var n = af[id]; | ||
80 | if(n && n.parentNode){ | ||
81 | n.parentNode.removeChild(n); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | }, | ||
87 | |||
88 | /** | ||
89 | * Clears the current filter. Note: with the "remove" option | ||
90 | * set a filter cannot be cleared. | ||
91 | */ | ||
92 | clear : function(){ | ||
93 | var t = this.tree; | ||
94 | var af = this.filtered; | ||
95 | for(var id in af){ | ||
96 | if(typeof id != 'function'){ | ||
97 | var n = af[id]; | ||
98 | if(n){ | ||
99 | n.ui.show(); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | this.filtered = {}; | ||
104 | } | ||
105 | }; | ||