Hello @arjunvasisht!
Impressive, you went quite far! Thank you very much for this perfectly runnable sample, I was able to run it here and see exactly what you meant.
Now, just try to replace your
beforerecorddrop
function with this:
var beforerecorddrop = function (node, data, overModel, dropPosition, dropFn) {
// debugger;
var draggedRecord = data.records[0].data
var draggedNode = App.TreePanel1.store.getNodeById(draggedRecord.id);
var srcTreeRootNode = App.TreePanel1.getRootNode();
// Fill an array with the path (from leaf to root)
var folderHierarchy = [];
var parentNode = draggedNode.parentNode;
while (parentNode != null && parentNode.id != srcTreeRootNode.id) {
folderHierarchy[folderHierarchy.length] = parentNode;
parentNode = parentNode.parentNode;
}
var curDestNode = overModel;
if (curDestNode.isLeaf()) {
// Dropped on a leaf that is also root?
if (curDestNode.isRoot()) {
return false;
}
// Move one level upper, to an actual folder node.
curDestNode = curDestNode.parentNode;
}
// Walk from shallowest to deepest path nodes, creating them as necessary
for (var i=folderHierarchy.length - 1; i >= 0; i--) {
var thisNode = folderHierarchy[i];
// Check if the folder already exists
var parentExists = false;
for (var j in curDestNode.childNodes) {
if (curDestNode.childNodes[j].data.text == thisNode.data.text) {
parentExists = true;
break;
}
}
// If not, then make a copy of the node into the destination tree
if (!parentExists) {
curDestNode.appendChild(thisNode.copy());
}
// Get child node on dest tree
for (var j in curDestNode.childNodes) {
if (curDestNode.childNodes[j].data.text == thisNode.data.text) {
curDestNode = curDestNode.childNodes[j];
break;
}
}
}
// Drop a copy of the node in the deepest level of the structure created
curDestNode.appendChild(draggedNode.copy());
// Do not continue normal node drop operation.
return false;
};
I am pretty sure it will get next to what you need.
Notice the
return false;
in the end. I am pretty much replacing all the drop procedure for my own and telling drag&drop to do nothing else.
In this example, you may notice that:
- you can drop a same record twice: it will contain same description but different internal id.
- on the end of the drop process, it plays the 'drop cancel' animation
- after dropping one sub-item that haves its sub-folders created, if you drop another item from the same sub-folder, you have to drop it on the root, or else it will just doubley-create sub-folders. If this is not your intended behavior, and want to always get the same folders hierarchy, just use instead of
overModel
in
var curDestNode
,
overModel.getOwnerTree().getRootNode()
. You can avoid unnecessary queries (if the dropped folder is root) by:
if (overModel.isRoot()) {
curDestNode = overModel;
} else {
curDestNode = overModel.getOwnerTree().getRootNode();
}
So, I believe this is not exactly what you need, but a much better starting point for you to trim it down and make it work exactly as you need.
Notice also I've didn't keep a code behind call, as this guarantees faster code execution (without client-server round trip).
I hope this helps!