Drag and Drop on leaf nodes

I set up a TreeGrid to accept drag and drop on leaf nodes:

…
canDropOnLeaves: true,
canReparentNodes: true,
canReorderRecords: true,
dragDataAction: “move”,
…

The intention is that any node (leaf or folder) can being dropped onto any other node (leaf or folder) for reparenting.

All works as advertized. However there is one minor UI issue that causes some confusion. When canReorderRecords is set to true, a ‘separator line’ appears between each node as the mouse moves. It’s difficult to tell which node you are actually dropping onto and in fact the separator line in this instance is counter-intuituive since one would expect the drop node to be the one above the separator line not below it. Technically, canReorderRecords gives a false impression of what we would like to see.

If I turn canReorderRecords off, folderDrop() never gets executed in the cases where both drag and drop nodes share the same parent. Is there any combination of switches I can set to both highlight the actual node the mouse is hovering over as well as insure folderDrop() gets called with the correct arguments?

Thanks for your help,
-paul

BTW - still on rel 7

Would love to see an equivalent version of folderDrop() (maybe nodeDrop()?) that would work with just the following switches:

canDropOnLeaves: true,
canReparentNodes: true,
dragDataAction: “move”,
…

that takes the same arguments (nodes, folder, index, sourceWidget) with the distinction that the folder being dropped onto is the actual leaf.

Also, would love some switch that would turn on node highlighting during drag and drop when the mouse is over a drop node.

-paul

Use these settings:

        canDragRecordsOut:true,
        canAcceptDroppedRecords: true,
        canDropOnLeaves: true,
        dragDataAction: "move"

canReparentNodes won’t work because you’re dropping on leaves, not parents.

I tried these switches but they still prevent dropping a leaf node onto another leaf when they both share the same parent. (“The item already contains a child with that name.” - message)

Specifically, the situation is as follows:

parent1
child1
child2

I’m trying to drop child1 onto child2.

-p

If this is a legal situation for you then you’ll also need to override willAcceptDrop() to return true in this case.

I tried overriding willAcceptDrop() but folderDrop() is still not being executed. (i.e. still getting “The item already contains a child with that name.” message)

I made willAcceptDrop() as general as possible just to test:


willAcceptDrop: function() {
if (this == EventHandler.getDragTarget()) {
return true;
}
return false;
},
[/]

Can’t seem to get by the grid checking for children with the same parent.

-p

Sorry about the formatting -

willAcceptDrop: function() {
if (this == EventHandler.getDragTarget()) {
return true;
}
return false;

Ah, sorry, because this is a drop on a leaf, folderDrop does not apply (no folder). Instead, add a handler for the earlier and more general DropEvent. This will bypass all checks, but doesn’t provide the same convenience parameters - you can find out the coordinate that was dropped on via getEventRow().

I can’t seem to find DropEvent in the docs. I assume you mean do something like this:

canAcceptDrop: true,
drop: function() {
  // handle the drop here
  var widget = EventHandler.getDragTarget();
  if (widget == this) {
     var row = this.getEventRow();
     var record = this.getRecord(row);
   // etc
}

Yes, exactly. “drop” is an event inherited from Canvas.

I have a tree that has folders AND leaves that can be dropped on…when I provide a “drop” event for the treegrid, it always calls that and does not look to call folderDrop..how do I provide the drop event ONLY for tree nodes that are leaves and folderDrop for tree nodes that ARE folders?

If you have overridden drop, call Super() to have folderDrop still be called normally.

Hmm..ok. onFolderDrop is called properly now…but I’m back to square one with my problem. I have a tree node that is marked as isFolder=false, my tree grid is marked as canDropOnLeaves=true, but when I try to drop an object into that node, I see the forbidden sign and on drop method has not been called…you mentioned that providing the drop method skips on drop validation?

willAcceptDrop() is called to determine drop eligibility. This method is overriden on TreeGrid with docs that explain TreeGrid-specific checks that it performs - take a look at these docs for various cases that could apply and would forbid dropping.

Found wrong logic in my willAcceptDrop - that’s why it wasn’t allowing me. but now the question is, in willAcceptDrop, how do I find the leaf node that the user is dropping into? When I call this.getDropFolder() I obviously would not get the node I want…is there a getDropNode() or something on the tree grid? I can’t seem to find the function in the lib

I think I may have found the issue - so when I was testing with 9.0, for leaf drops I would use the getDropIndex() to find the node that the user is dropping on - because in 9.0, it would give me the index of that node. But in 8.3, getDropIndex() gives me the NEW index just underneath the node. I don’t want to blindly check for getDropIndex() -1 especial since it is fixed in 9.0. We cannot currently upgrade because there are issues with rendering that we have yet to debug.

getEventRow(), inherited from ListGrid, gives you the row that the mouse is over.

Thanks that does the job