PDA

View Full Version : [3.0] Solution for a Local Tree



Ronaldo
31 Jul 2009, 4:59 AM
Hi all,

This is not a real extension, but more a tip: I needed a local tree that does not load data from the server, but is loaded from an array client side.
AFAIK, the TreePanel is configured to always go to the server to request data, which is not what I wanted.

Now the treeLoader, nor the ASyncTreeLoader have a mode='local' property, like the Store.
So here's my solution to use a 'mode=local' tree:


MyTree = Ext.extend(Ext.tree.TreePanel, {
layout : 'fit',
initComponent : function() {
this.root = {
id :'root',
text :'Root',
draggable :false,
type :'folder',
expand :true,
leaf: false,
loaded:true
};

this.loader = new Ext.tree.TreeLoader({
baseAttrs: {loaded: true} // Makes every ASyncNode think it's already loaded
});

MyTree.superclass.initComponent.call(this);
},
loadData : function(node, data) {
if(Ext.isString(data)) {
try {
data = Ext.decode(data);
}catch(e){
alert('error!'+e);
return;
}
}
// data is supposed to be an array now
try {
node.beginUpdate();
this.loadNode(node, data);
node.endUpdate();
}catch(e){
alert('error!'+e);
}
this.root.expand();
},
loadNode: function(node, data) {
for(var i = 0, len = data.length; i < len; i++) {
var d = data[i];
var n = this.loader.createNode(d);
if(n){
node.appendChild(n);
}
for(var p in d) {
if(Ext.isArray(d[p])) {
var subNode = this.loader.createNode({
text: p,
leaf: false
});
if(subNode){
n.appendChild(subNode);
}
this.loadNode(subNode, d[p]);
}
}
}
},
...
}

In your clientcode, you can now load the tree via:


MyTree.loadData(this.root,
[{id:123, text:'sub1', kids:[{id:11, text:'sub1-1'},{id:12, text:'sub1-2'}]}]
);

Bear in mind that when reloading nodes, you might need to delete them first...

Ronaldo

Condor
31 Jul 2009, 6:11 AM
But Ext already has support for this:

var node = new Ext.tree.TreeNode();
var tree = new Ext.tree.TreePanel({
title: 'TreePanel',
rootVisible: false,
autoScroll: true,
loader: new Ext.tree.TreeLoader({
preloadChildren: true
}),
root: node
});
new Ext.Viewport({
layout: 'fit',
items: tree
});
node.attributes.children = [{
text: 'Branch 1',
expanded: true,
children: [{
text: 'Leaf 1a',
leaf: true
},{
text: 'Leaf 1b',
leaf: true
}]
},{
text: 'Leaf 2',
leaf: true
}];
node.getLoader().load(node);

(or directly specify the children as a config option of the root node - that way you don't need to load anything)

Animal
31 Jul 2009, 6:25 AM
or



var node = new Ext.tree.AsyncTreeNode({
children: [{
text: 'Branch 1',
expanded: true,
children: [{
text: 'Leaf 1a',
leaf: true
},{
text: 'Leaf 1b',
leaf: true
}]
},{
text: 'Leaf 2',
leaf: true
}]
});
var tree = new Ext.tree.TreePanel({
title: 'TreePanel',
rootVisible: false,
autoScroll: true,
loader: new Ext.tree.TreeLoader({
preloadChildren: true
}),
root: node
});
new Ext.Viewport({
layout: 'fit',
items: tree
});

Condor
31 Jul 2009, 6:26 AM
That's what my footnote said.

ps. You can even simplify that to:

var node = {
children: [{
text: 'Branch 1',
expanded: true,
children: [{
text: 'Leaf 1a',
leaf: true
},{
text: 'Leaf 1b',
leaf: true
}]
},{
text: 'Leaf 2',
leaf: true
}]
};

Ronaldo
31 Jul 2009, 6:28 AM
Ai, so many options... Thanks, I didn't find it.

My loadData method however provides a little bonus then; the recursive method converts all nested array properties to child nodes. Thus, the data I provide doesn't have to have a 'children' property, but can simply be a nested array.

Ronaldo

0411020211
25 Aug 2009, 2:09 AM
I have tried all above,they work well in FF but none of them work in Ext3.0 & IE7.
please help!!!

Condor
25 Aug 2009, 2:32 AM
Define 'doesn't work'...

ps. Are you sure you don't have a trailing comma somewhere in your code?