View Full Version : problem copying children nodes
yehosef
22 Jul 2007, 6:27 AM
Hello,
I'm new to Ext and working on my first application. I need something like the two-trees demo and have used that for my starting point. My application needs that the left tree act as the "source" and dragging from tree to tree2 just copies the structure.
Here's what I've come up with from looking around a few posts in the forum:
tree2.on("beforenodedrop", function(de) {
if (de.source.el !=this.el) {
de.dropNode = copyDropNode(de.dropNode);
return true;
}
return false;
});
function copyDropNode(node){
var newNode = new Ext.tree.TreeNode(Ext.apply({}, node.attributes));
for(var i=0; i < node.childNodes.length; i++){
n = node.childNodes[i];
if(n){
newNode.appendChild(copyDropNode(n));
}
}
return newNode;
}
Everything works fine except that node.childNodes.length seems to always return 0 and the child structure doesn't get copied. Then I tried hardcoding in the length in place of node.childNodes.length and it also didn't work - it seems as if node.childNodes isn't there - I'm not sure.
I'm using Ext JS Library 1.1 RC 1.
I'm new to javascript so maybe I'm missing something obvious. Any ideas?
just a quick guess:
change
n = node.childNodes[i];
to
var n = node.childNodes[i];
otherwise your recursive function will work with a global variable "n" - not going to work...
yehosef
22 Jul 2007, 11:27 AM
Thanks for the tip - It could be that would be a factor, but it didn't fix the problem.
I noticed that if I expand the parent in the left tree so I see the children, when I copy the parent the children get copied also (but collapsed.) I think I maybe see what's happening.
Before a node has ever been expanded, it doesn't have any children as far as Ext is concerned and when I copy the parent - it doesn't copy the children because they don't exist. Once I load them and they exist in the tree - when I copy the tree - the children are copied also (because they exist).
This makes sense and matches what is happening (if I expand and collapse a node, the children are copied, but copying without expanding does not copy children). But this is not what I want to happen - How could I get it to copy the children also. I haven't gotten to the stage of making the drop change the database so perhaps on the drop - I'll copy the structure there (serverside). Then the only thing left would be to make the client side show the plus in the drop area when there are children.
Is that a big tree structure you are loading into the TreeView? If not, you just could load it all at once with all its children. AFAIK you just have to add a "children" array to the JSON you return. Current Ext implementations should then build the whole tree at once. (I remember jack saying so - never tried that because I already wrote my own TreeLoader for that)
Example JSON:
[{"text":"node1","id":"node1",children:[
{"text":"node1-1","id":"node1-1",children:[
{"text":"node1-1-1","id":"node1-1-1"}
]},
{"text":"node1-2","id":"node1-2"}
]}]
If you cannot load the whole tree at once you could try to copy the loader from the source node to the target node:
function copyDropNode(node){
var newNode = new Ext.tree.TreeNode(Ext.apply({}, node.attributes));
newNode.loader = node.loader;
for(var i=0; i < node.childNodes.length; i++){
var n = node.childNodes[i];
if(n){
newNode.appendChild(copyDropNode(n));
}
}
return newNode;
}
The copyDropNode function does not copy any state from the source node to the new node. If you want to copy that as well you have to add it:
function copyDropNode(node){
var newNode = new Ext.tree.TreeNode(Ext.apply({}, node.attributes));
for(var i=0; i < node.childNodes.length; i++){
var n = node.childNodes[i];
if(n){
newNode.appendChild(copyDropNode(n));
}
}
if (node.isExpanded()) {
newNode.expand(false, false);
}
return newNode;
}
yehosef
23 Jul 2007, 3:38 AM
Thanks for the tips - I'm new to Ext so it's a big help.
The tree can be a little big (might be 10,000 final leafs with 200-300 branches at different levels in between. I assumed it would be to unwieldy to load at once - do you have experience otherwise? From the database side alone it'll be a little slow - but it might be something I could compromise on for the sake of simplicity.
Do you have tips/code/forum threads that give examples on writing the code (I use php) to save the node structure?
BernardChhun
23 Jul 2007, 3:50 AM
Thanks for the tips - I'm new to Ext so it's a big help.
The tree can be a little big (might be 10,000 final leafs with 200-300 branches at different levels in between. I assumed it would be to unwieldy to load at once - do you have experience otherwise? From the database side alone it'll be a little slow - but it might be something I could compromise on for the sake of simplicity.
Do you have tips/code/forum threads that give examples on writing the code (I use php) to save the node structure?
hey I might have a trick up my sleeve here...here's how I do it to manage such enormous trees.
there's tree_1 and tree_2. Both are using a TreeLoader to fetch data from the server.
when you transfer a node from tree_1 to tree_2, you just need to send a XHR call to your server side specifying the id of the node that was sended and then you reload tree_2. you don't need to specify its children at this point since that will be found out by the server side. The only annoying thing here is that tree_2 will flicker a bit to load the data.
:)
Has for the node structure, I always add a custom PATH attributes to my nodes that have been fetched with the Loader.
it would look like this
/grand-parent-id/parent-id/node-id
that way I always have a node's context. There's a lot of way in managing such things. You may build a whole table structure defining the relationship between your nodes...but that can be quite lengthy.
We obviously didn't have the time to do it...so we prefer to add some context and fetch the children based on that.
yehosef
25 Jul 2007, 11:12 AM
Thanks for the tips - I'm going to try to apply them.
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.