PDA

View Full Version : Code contrib: Multi-node support in TreeDragZone



rad_nq
12 Mar 2007, 12:26 PM
While multi-node selection worked since 0.4 with the MultiSelectionModel you cannot (since last looked in 1.0 code) actually select multiple nodes and perform a Drag and Drop operation with them. Selection falls back to a single node and that is DnD'ed.

The following is a TreeDragZone subclass to allow for multiple node selection Drag and Drop operations.

Note: the render() in Tree has to be completely copied as I have not been able to create a standalone TreeDragZone instance and then set it to the tree. Exceptions all over the place so if anyone knows a better way of making and setting the "this.dropZone" on a TreePanel post a reply.

This was coded against 0.4 so adjust for 1.0 code as needed. (We are waiting for the alpha run to complete before migrating).



::override your TreePanel's render function with something like:
treePanel.render = function(){
}

The code body of the function is identical to the original except change:


if((this.enableDD || this.enableDrag) && !this.dragZone){
this.dragZone = new YAHOO.ext.tree.TreeDragZone(this, this.dragConfig || {
ddGroup: this.ddGroup || 'TreeDD',
scroll: this.ddScroll
});
}
with:

if((this.enableDD || this.enableDrag) && !this.dragZone){
this.dragZone = new RAD.tree.MultiDragZone(this, this.dragConfig || {
ddGroup: this.ddGroup || 'TreeDD',
scroll: this.ddScroll
});
}

And now the implementation of MultiDragZone:



YAHOO.extendX(RAD.tree.MultiDragZone, YAHOO.ext.tree.TreeDragZone, {
/**
* TreeDragZone does not support multiple selection very well. So if we are using
* a multi select model, then handle it appropriately.
*/
onInitDrag: function(e){
if(this.tree.getSelectionModel().getSelectedNodes){
return YAHOO.ext.tree.TreeDragZone.superclass.onInitDrag.call(this, e);
} else {
return RAD.tree.MultiDragZone.superclass.onInitDrag.call(this,e);
}
},
/**
* This returns the XY coordinates to send the animating repair ghost from failed DnD.
* We just grab the last selected item and focus the drop there. Should perhaps be something else?
*/
getRepairXY: function(e, data){
var result;
if(data.node){//invocation
result = RAD.tree.MultiDragZone.superclass.getRepairXY.call(this,e, data);
}else if(data.treeNodes){
result = data.treeNodes[data.treeNodes.length - 1].getUI().getDDRepairXY();
}else {
result = false;
}
return result;
},


/**
* TreeDragZone does not support multiple selection very well.
*/
beforeInvalidDrop: function(e, id){
return YAHOO.ext.tree.TreeDragZone.superclass.beforeInvalidDrop.call(this, e, id);
},

/**
* Gets the TreeNodes contained in data that are to be copied.
* @param data : The DnD object generated by getDragData
* @param targetNode : The node drop will be applied to.
* @param point : ??
* @param e : ??
*/
getTreeNode: function(data, targetNode, point, e){
return data.treeNodes;//move or copy will be handling this.
},
getDragData: function(e){
var dragData = YAHOO.ext.dd.Registry.getHandleFromEvent(e);

var selModel = this.tree.getSelectionModel();
if(dragData != null && selModel.getSelectedNodes){//Only do non-standard logic IF we have multiple selections.
//Ensure the node is selected.
if(!selModel.isSelected(dragData.node)){
//selModel.select(dragData.node, null, true);
}

var selNodes = selModel.getSelectedNodes();

if(selNodes.length > 1){
//We need to build up array of selected Tree elements.
var htmlNodes = new Array();
for(var i=0, len = selNodes.length; i< len; i++){
htmlNodes[i] = selNodes[i].getUI().getEl().firstChild;
}

dragData = {
nodes: htmlNodes,
multi: true,
treeNodes: selNodes
};
var div = document.createElement('div');//Create the multi element "ghost"
div.className = 'multi-proxy';//ydd-drag-proxy and ydd-drag-ghost
for(var i=0, len = htmlNodes.length; i< len; i++){
div.appendChild(htmlNodes[i].cloneNode(true));
//does automagic nextline stuff.
}
dragData.ddel = div;


}
}
return dragData;
}
});

rad_nq
12 Mar 2007, 12:28 PM
The previously suggested fix for the Node rendering in the forums MUST be applied if you want it to work in Firefox.
See:
http://www.yui-ext.com/forum/viewtopic.php?t=3217&highlight=multiselectionmodel

BernardChhun
13 Mar 2007, 3:54 AM
that will be handy thanks.