/*!
|
* Ext JS Library 3.1.0
|
* Copyright(c) 2006-2009 Ext JS, LLC
|
* licensing@extjs.com
|
* http://www.extjs.com/license
|
*/
|
/**
|
* @class Ext.tree.TreeFilter
|
* Note this class is experimental and doesn't update the indent (lines) or expand collapse icons of the nodes
|
* @param {TreePanel} tree
|
* @param {Object} config (optional)
|
*/
|
Ext.tree.TreeFilter = function(tree, config){
|
this.tree = tree;
|
this.filtered = {};
|
Ext.apply(this, config);
|
};
|
|
Ext.tree.TreeFilter.prototype = {
|
clearBlank:false,
|
reverse:false,
|
autoClear:false,
|
remove:false,
|
|
/**
|
* Filter the data by a specific attribute.
|
* @param {String/RegExp} value Either string that the attribute value
|
* should start with or a RegExp to test against the attribute
|
* @param {String} attr (optional) The attribute passed in your node's attributes collection. Defaults to "text".
|
* @param {TreeNode} startNode (optional) The node to start the filter at.
|
*/
|
filter : function(value, attr, startNode){
|
attr = attr || "text";
|
var f;
|
if(typeof value == "string"){
|
var vlen = value.length;
|
// auto clear empty filter
|
if(vlen == 0 && this.clearBlank){
|
this.clear();
|
return;
|
}
|
value = value.toLowerCase();
|
f = function(n){
|
return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
|
};
|
}else if(value.exec){ // regex?
|
f = function(n){
|
return value.test(n.attributes[attr]);
|
};
|
}else{
|
throw 'Illegal filter type, must be string or regex';
|
}
|
this.filterBy(f, null, startNode);
|
},
|
|
/**
|
* Filter by a function. The passed function will be called with each
|
* node in the tree (or from the startNode). If the function returns true, the node is kept
|
* otherwise it is filtered. If a node is filtered, its children are also filtered.
|
* @param {Function} fn The filter function
|
* @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the current Node.
|
*/
|
filterBy : function(fn, scope, startNode){
|
startNode = startNode || this.tree.root;
|
if(this.autoClear){
|
this.clear();
|
}
|
var af = this.filtered, rv = this.reverse;
|
var f = function(n){
|
if(n == startNode){
|
return true;
|
}
|
if(af[n.id]){
|
return false;
|
}
|
var m = fn.call(scope || n, n);
|
if(!m || rv){
|
af[n.id] = n;
|
n.ui.hide();
|
return false;
|
}
|
return true;
|
};
|
startNode.cascade(f);
|
if(this.remove){
|
for(var id in af){
|
if(typeof id != "function"){
|
var n = af[id];
|
if(n && n.parentNode){
|
n.parentNode.removeChild(n);
|
}
|
}
|
}
|
}
|
},
|
|
/**
|
* Clears the current filter. Note: with the "remove" option
|
* set a filter cannot be cleared.
|
*/
|
clear : function(){
|
var t = this.tree;
|
var af = this.filtered;
|
for(var id in af){
|
if(typeof id != "function"){
|
var n = af[id];
|
if(n){
|
n.ui.show();
|
}
|
}
|
}
|
this.filtered = {};
|
}
|
};
|