I've been developping this functionnality for a project I'm working on, and I though it might be usefull to someone.
With this small code you can search in any opened node (similar to the CTRL + F function of any program), it searches the next node corresponding to the text you typed.
But i also added the partial search: use * to match any part of a word --> *word (the searched text ends with the searched word), *word* and word*
You can easily disable this by removing the red part of the code.
This code isn't fully perfect, it doesn't take into account any special character used in regexp, if you want it to be safe you should add a filter for these characters (ex: replace * by \*)
I used a statusbar for the search field and buttons:
Code:
bbar: new Ext.ux.StatusBar({
defaultText: statusMessage,
id: 'right-statusbar',
statusAlign: 'right', // the magic config
items: [{
xtype: 'textfield',
blankText: "Enter a word to search...",
id: "searchField",
width: 150,
listeners: {
'focus' : function(){
var statusBar = Ext.getCmp('right-statusbar');
statusBar.setStatus({
text:'Hint: Use * for a partial search.'
});
}
}
}{
xtype: 'button',
text: "Search",
id: "searchButtonOpened",
scope: this,
handler: loadFn.createCallback('searchButtonOpened')
}]
})
The callback function :
Code:
var loadFn = function(btn){
btn = Ext.getCmp(btn);
var searchText = Ext.getCmp('searchField').getValue();
if(btn.id == 'searchButtonOpened') {
if(searchText.substring(searchText.length-1,searchText.length)=="*") {
if(searchText.substring(0,1)=="*")
searchText = searchText.replace('*','');
else
searchText = "^"+searchText.replace('*','');
} else if(searchText.substring(0,1)=="*")
searchText = searchText.replace('*','')+"$";
var tree = Ext.getCmp('tree');
var searchRoot = tree.selModel.selNode || Ext.getCmp('tree').root; // if no selection use root node
var searchedNode = searchInAllNodes(searchRoot,searchText,searchRoot.id);
if(searchedNode) { // if match found, select the node
searchedNode.select();
} else { // else restart search from root (loop)
var searchRoot = Ext.getCmp('tree').root;
var searchedNode = searchInAllNodes(searchRoot,searchText,searchRoot.id);
if(searchedNode) {
searchedNode.select();
} else { // if no match found at all
var statusBar = Ext.getCmp('right-statusbar');
statusBar.setStatus({
text:'No result'
});
}
}
}
};
And finally the recursive search function :
Code:
function searchInAllNodes(n,txt,ignoreId){
var cleanTxt = txt.toLowerCase().replace('*','').replace('$','').replace('^','');
if(n.id!=ignoreId && n.text.toLowerCase().match(txt.toLowerCase()) && n.text.toLowerCase().match(cleanTxt)) {
return n;
} else {
if(!n.hasChildNodes() && n == n.parentNode.lastChild) { // si le noeud n'a pas d'enfants et est le dernier de la branche
if(n.parentNode.nextSibling != null) {
var res = searchInAllNodes(n.parentNode.nextSibling,txt,ignoreId);
if(res != 0) // si on retourne autre chose que 0 --> bingo
return res;
return 0;
} else
return 0;
} else {
for(var i=0; i<n.childNodes.length; i++)
{
var res = searchInAllNodes(n.childNodes[i],txt); // check dans chaque noeud enfant
if(res != 0) // si on retourne autre chose que 0 --> bingo
return res;
}
if(n.nextSibling != null) {
var res = searchInAllNodes(n.nextSibling,txt,ignoreId);
if(res != 0) // si on retourne autre chose que 0 --> bingo
return res;
}
return 0; // si on n'a eu que des 0, on retourne 0
}
}
}