So here is my version of your filter :
I just added a global parameter depth.
It can be specified by the constructor or as a parameter of the filter method.
Code:
// vim: ts=4:sw=4:nu:fdc=4:nospell
/*global Ext */
/**
* @class Ext.ux.tree.TreeFilterX
* @extends Ext.tree.TreeFilter
*
* <p>
* Shows also parents of matching nodes as opposed to default TreeFilter. In other words
* this filter works "deep way".
* </p>
*
* @author Ing. Jozef Sakáloš
* @version 1.0
* @date 17. December 2008
* @revision $Id: Ext.ux.tree.TreeFilterX.js 589 2009-02-21 23:30:18Z jozo $
* @see <a href="http://extjs.com/forum/showthread.php?p=252709">http://extjs.com/forum/showthread.php?p=252709</a>
*
* @license Ext.ux.tree.CheckTreePanel is licensed under the terms of
* the Open Source LGPL 3.0 license. Commercial use is permitted to the extent
* that the code/component(s) do NOT become part of another Open Source or Commercially
* licensed development library or toolkit without explicit permission.
*
* <p>License details: <a href="http://www.gnu.org/licenses/lgpl.html"
* target="_blank">http://www.gnu.org/licenses/lgpl.html</a></p>
*
* @forum 55489
* @demo http://remotetree.extjs.eu
*
* @donate
* <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
* <input type="hidden" name="cmd" value="_s-xclick">
* <input type="hidden" name="hosted_button_id" value="3430419">
* <input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif"
* border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
* <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
* </form>
*/
Ext.ns('Ext.ux.tree');
/**
* Creates new TreeFilterX
* @constructor
* @param {Ext.tree.TreePanel} tree The tree panel to attach this filter to
* @param {Object} config A config object of this filter
*/
Ext.ux.tree.TreeFilterX = Ext.extend(Ext.tree.TreeFilter, {
/**
* @cfg {Boolean} expandOnFilter Deeply expands startNode before filtering (defaults to true)
*/
expandOnFilter:true,
/**
* @cfg {int} depth automatically stop the filter at a specified depth level of the tree (defaults to true)
*/
depth:true
// {{{
/**
* 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.
* @param {int} depth {optional} the maxDepth parameter to stop the filter at.
*/
,filter:function(value, attr, startNode, depth) {
// expand start node
if(false !== this.expandOnFilter) {
startNode = startNode || this.tree.root;
this.depth = depth || true;
var animate = this.tree.animate;
this.tree.animate = false;
startNode.expand(true, false, function() {
// call parent after expand
Ext.ux.tree.TreeFilterX.superclass.filter.call(this, value, attr, startNode);
}.createDelegate(this));
this.tree.animate = animate;
}
else {
// call parent
Ext.ux.tree.TreeFilterX.superclass.filter.apply(this, arguments);
}
} // eo function filter
// }}}
// {{{
/**
* 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.
* Shows parents of matching nodes.
*
* @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;
// set the maxDepth
var maxDepth = this.depth;
var f = function(n) {
// if the depth of the checked node is strictly bigger than
// the max depth, always return true.
if(n.getDepth()>maxDepth){
return true;
}
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 true;
}
else {
n.ui.show();
var p = n.parentNode;
while(p && p !== this.root) {
p.ui.show();
p = p.parentNode;
}
return true;
}
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);
}
}
}
}
} // eo function filterBy
// }}}
}); // eo extend
// eof
so i have a trriger field configured as following :
Code:
{
width:200,
xtype:'trigger',
triggerClass:'x-form-clear-trigger',
onTriggerClick:function() {
this.setValue('');
ths.filter.clear();
},
id:'staffFilter',
enableKeyEvents:true,
listeners:{
keyup:{buffer:150, fn:function(field, e) {
if(Ext.EventObject.ESC == e.getKey()) {
field.onTriggerClick();
}
else {
var val = this.getRawValue();
var re = new RegExp('.*' + val + '.*', 'i');
ths.filter.clear();
// overwrite the deptg to 1
ths.filter.filter(re, 'text',null,1);
}
}}
}
}
and i finally obtain what i wanted in my tree with the filtered staff and all its children nodes :

i join the js file here for you to see and a .patch file.
Thanks for the fast reaction to my question,
Tom.