Start Building Professional
Web Apps Today


 
Categories Question details Back To List
Question  posted by Paul K on Jul 29, 2008 11:27
open dhtmlx forum
Save user data on drop

I've set up a grid and a tree control and I want to use drag and drop from the grid to the tree. The rows in the grid and the nodes in the tree have user data defined for them. I want to preserve the user data when cells are dropped into the tree.

The onDrop event for the tree control does not give me the id of the source (dragged) object. So in that event handler I can't get the userData of the source object to transfer to the new node.

How can the userData be copied?

Paul
Answer posted by Support on Jul 30, 2008 02:44
If you are moving rows from grid to tree, on moment of onDrop event, row will be already deleted from source grid, it is to late to copy userdata info.
You can use both onDrag and onDrop events

var temp;
tree.attachEvent("onDrag",function(row_id){
    temp = some_code_to_store_userdata(row_id);  
    return true;
});
tree.attachEvent("onDrop",function(tree_id){
    some_code_to_set_userdata(tree_id,temp);  
});
Answer posted by Paul K on Jul 30, 2008 10:52
I set enableMercyDrag to true for the grid control so the row is not deleted.

Answer posted by Paul K on Jul 30, 2008 11:07
I also experimented with setting the gridToTreeElement function on the grid.  That is, I replaced it with my own event handler.  The parameters for the handler have both the new tree node ID and the existing grid row ID.  While I can get the value of the userdata for the row, I cannot set it for the node in the tree.  I think when the function is called the node does not exist yet in the tree.

I test it by setting the value and immediately retrieving it:

function testGridtoTreeElement(treeObject, treeNodeId, gridRowId) {
    alert("grid to tree element, tree node id = " + treeNodeId + ", grid row id = " + gridRowId + ", item type = " + this.getUserData(gridRowId,"Item Type"));
    treeObject.setUserData(treeNodeId, "Item Type", this.getUserData(gridRowId,"Item Type"));
    alert("updated item type = ",treeObject.getUserData(treeNodeId,"Item Type"));  //  This displays an empty string
    return this.cells(gridRowId,0).getValue();

}

I also see the tree OnDrop event occurs after the gridToTreeElement function is called.  So I'll probably have to do what you suggested anyway.

Answer posted on Jul 30, 2008 12:07
I realized that this line in the above example:

    alert("updated item type = ",treeObject.getUserData(treeNodeId,"Item Type"));  //  This displays an empty string

should be:

    alert("updated item type = " + treeObject.getUserData(treeNodeId,"Item Type"));  //  This displays undefined.

But even so the item type is not set.

I ended up saving the row id in the onDrag event and using it in the onDrop event.  Setting the user data in the onDrop event does work.  (I save the row id because I may end up having more user data to transfer.)
Answer posted by Support on Jul 31, 2008 03:39
>>I think when the function is called the node does not exist yet in the tree.
Yes, this method called before tree node creation

While its not the best solution, next can be used as well

function testGridtoTreeElement(treeObject, treeNodeId, gridRowId) {
    var data=this.getUserData(gridRowId,"Item Type");
    window.setTimeout(function(){
        treeObject.setUserData(treeNodeId, "Item Type", data);
    },1);
    return this.cells(gridRowId,0).getValue();
}
Answer posted by Support on Jul 31, 2008 03:41
The order of events is the next
    - onDrag ( grid item exists, tree item not exists )
    - gridToTreeElement ( grid item exists, tree item not exists )
    - onDrop ( grid item not exists, tree item exists )

Tree doesn't allow to set user data to not existin item, so the only momen when data may be sent is onDrop event ( snippet above uses single-thread nature of javascript, so it run setUserData code when current thread finished, which mean tree item exists for sure )