PDA

View Full Version : treeloader doesn't allow leaf node that can containChildren



simeon
21 Feb 2007, 12:24 PM
When I load a tree using the treeloader



loader: new Tree.TreeLoader({dataUrl:'get-nodes.jsp'}),


That loads the following JSON:



[
{
"text":"Folder name here",
"id":"1",
"cls":"folder"
},
{
text: "This should be a leaf that can contain children",
"id":"156735184315",
"cls":"message",
"leaf":true,
"allowDrop":true,
"allowChildren":true
}
]



the second node should be a leaf and not have the plus expander, and also support the addition of children to it. an example would be an empty folder

Currently that node does not allow me to add to it using drag and drop. I have tried removing the leaf:true config property, but it then gets the plus expander even though it has no children. Not sure how to say it allowsChildren but is currently so unpopular that no one wants to make any children with it. :D

When I use the following config parameters to create the nodes manually and not through treeloader, I get a node that is leaf, doesn't have an expander plus, and allows children. (ie. its an empty folder) This is what I would expect from the above config as well. unfortunately the config below loaded into treeloader results in a node that has the plus expander by default.



var node = selectedNode.appendChild(new Tree.TreeNode({
text:'New Message',
id:"TEMP_JS_GUID_HERE2",
cls:'message',
allowDrag:true
}));



So, I believe there is a bug in treeloader that results in different interpretations of the node config than when created explicitly. I tried to step through the treeloader code with firebug, but I am new to all this obj oriented JS and was hopelessly lost.

Simeon

jack.slocum
21 Feb 2007, 12:55 PM
Unfortunately there's no way for an AsyncTreeNode (ATN) to know if it has children or not without making a server request. So all ATNs have a plus by default. The leaf property is a way to tell it that it has no children and will never have any children. When it is set to true, the TreeLoader creates a TreeNode instead of an ATN.

There are 2 options:

A workaround that should work (without a server call):


[
{
text: "This should be a leaf that can contain children",
"id":"156735184315",
"cls":"message",
"children":[], // <-- preload children (which is no children)
"expanded": true, // expand immediately to prevent plus
"allowDrop":true,
"allowChildren":true
}
]

If that isn't a good solution for you (or doesn't work for some reason), you can also implement a different createNode function on your TreeLoader. It was separated out from the rest of the logic specifically for this type of situation:

Here's the default:

/**
* Override this function for custom TreeNode node implementation
*/
createNode : function(attr){
if(this.applyLoader !== false){
attr.loader = this;
}
return(attr.leaf ?
new Ext.tree.TreeNode(attr) :
new Ext.tree.AsyncTreeNode(attr));
}

You can either override the function completely using Ext.extend() or simply intercept it and use some custom attr:


loader.createNode = function(attr){
if(attr.someNonLeafAttr){
return new TreeNode(attr);
}
return Ext.tree.TreeLoader.createNode.call(this, attr);
};

Please let me know if these work for you.

simeon
21 Feb 2007, 1:11 PM
Thanks jack,

Using the config changes in the first example worked perfectly!

The second and third option went a bit over my head, but I will look at it later.
If I compare it against what's currently in treeLoader it may make more sense to me.

It feels like my learning curve is starting to flatten out though. :D

Simeon

jack.slocum
21 Feb 2007, 1:25 PM
I figured the first would be easiest. In case you haven't experimented with it, you can actually use that "children" property to lazy load your whole tree or specific braches in a single HTTP call. The nodes aren't actually created until the user expands the node. It's really fast and something unique (I believe) to the Ext TreePanel.

simeon
21 Feb 2007, 1:37 PM
Wow, no I didn't realize that. That's really good to know.

I was building my tree with one request per folder expansion.

Preloading the children in the JSON should significantly reduce the roundtrips to the server and any cumlative latency it caused.

Thanks for the tip. That might be a good comment to put with the tree examples since I was building based on my studies of your tree examples.

Simeon

dselkirk
23 Feb 2007, 10:33 AM
hey, been doing some port of my existing code as well and have a similar problem. I tried the above without success. My problem is I use to be able to drag and add a any item to another. for example, drop a leaf on to another to create a folder. any ideas.

cheers

simeon
23 Feb 2007, 10:44 AM
make sure you have the same "ddGroup" attribute for both trees. Also make sure you have enableDD:true. Other than that you will likely need to post some code to look at.

My tree initialization code


var tree = new Tree.TreePanel('tree-body', {
animate:true,
loader: new Tree.TreeLoader({dataUrl:'get-nodes.jsp'}),
enableDD:true,
ddGroup: 'hotlineDD',
containerScroll: true
});

var root = new Tree.AsyncTreeNode({
text: 'I am root. ',
draggable:false,
icon: 'images/ic_tree_hotline.gif',
id:'rootNode',
type:0
});
tree.setRootNode(root);
tree.render();
root.expand();
tree.getSelectionModel().select(root);


My data looks like this:



[
{"text":"This is a message description","id":"1","cls":"message","type":1},
{
text: "This is a message that has no children but can contain children",
"id":"156735184315",
"cls":"message",
"children":[],
"expanded": true,
"security":1,
"type":1
},
{
text: "This is a data node with children included",
"id":"156735184315",
"cls":"message",
"children": [
{"text":"Main Office Number","id":"6","children":[],"expanded": true,"cls":"message","type":1},
{"text":"Houston Office Number","id":"7","children":[],"expanded": true,"cls":"message","type":1},
{"text":"Dallas Office Number","id":"8","children":[],"expanded": true,"cls":"message","type":1},
],
"expanded": false, // expand immediately to prevent plus
"security":1,
"allowDrop":true,
"type":1
}
]



Simeon

dselkirk
23 Feb 2007, 11:34 AM
thx for the reply. didn't help. i'm using a single tree loaded from the server with a customized loader. The date present cms page structure. a page can be access directly and can be a parent to another. In .40 I was able to drag a leaf and add it to another leaf. 1.0 doesn't seem to to that anymore, i just get sorting functions.

simeon
23 Feb 2007, 11:39 AM
in the 1.0 tree. nothing can be added to a leaf via dragdrop.
if it has leaf:true as an attribute, then it will not accept a child.

remove the leaf attribute, and use this instead:
"children":[],
"expanded": true,

Simeon

dselkirk
23 Feb 2007, 12:00 PM
that did the trick, cheers