/** * @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 of the function (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 = {}; } };