PDA

View Full Version : DD into overlapping zones



danikenan
20 Oct 2009, 11:10 PM
Hi,

Our application allows a user to arrange a warehouse by dragging items from one shelf into another (shelves are implemented as DataViews inside Panel). In addition, we have a hovering leftovers shelf, implemented as a hovering Ext.Window (within it, again, a Panel and a dataview).

For each panel we create a seperate DropZone. For each view we create a seperate DragZone.

It works great expect when we drop items on the leftovers window which always hovers and overlaps one or more shelves. In case of a drop on the leftovers dropzone we get 2 calls to Ext.dd.DropZone.onNodeDrop, on for the dropzone inside the leftovers window and one for the shelf below the cursor at the time of the drop.

What if worse, the order at which the two calls are made is inconsistent. Sometimes we get the call for the window first, and sometimes it is the second call.

How can I ensure that the dropzone below the leftover window does not get called when a drop is made into the floating leftovers window.

10x

hello2008
22 Oct 2009, 7:22 AM
seems Ext.dd package is something out of Ext Core, it's better to appear at Ext: Help (http://www.extjs.com/forum/forumdisplay.php?f=40) section

su27
27 Aug 2010, 7:46 PM
i got same issue and fixed it. i don't think this could help you, it's too late. but i like to share it with all of you guys.
the whole idea is based on :
when drag target is dropped on overlapped drop zones, the e argument contains the drop zone div(or it's child div at any depth)

1.set an unique id for each drop target. i name it dropId, you can name it as you wish, just don't conflict with existing property.
first drop zone

var sdGrid = Ext.getCmp('sdGridSdPanel');
// set this unique id dropId = courseDDGroupSdPanel
sdGrid.body.dom.dropId = 'courseDDGroupSdPanel';
new Ext.dd.DropTarget(sdGrid.body.dom,{
ddGroup : 'courseDDGroup',
notifyDrop : function(ddSource, e, data){
//check if this is the dropzone on top
//this id must match sdGrid.body.dom.dropId
if(isDropTarget(e.target,'courseDDGroupSdPanel')){
//do things u need to do
return true;
}
}
});

second drop zone

var courseTab = Ext.getCmp('courseTab');
courseTab.body.dom.dropId = 'courseDDGroupCoursePanel';
new Ext.dd.DropTarget(courseTab.body.dom,{
ddGroup : 'courseDDGroup',
notifyDrop : function(ddSource, e, data){
if(isDropTarget(e.target, 'courseDDGroupCoursePanel')){
// implement your logic here
}
}
});

notice: these two drop zones have same ddGroup name.
of course, you have to set your drap target with same ddGroup name as well.

2. check if this is the top drop zone
when a drop zone is assigned to a root element, all of this element's childs(at any depth) can listen notifyDrop.
so usually, the target element is a child element of the root element, rather than the root element. u have to check target element's parent, and parent's parent, and...so on. until it's null, or dropId doesn't match.

function isDropTarget(node, dropId){
if(!node){
return false;
}
if(node.dropId == dropId){
return true;
}else{
return isDropTarget(node.parentElement, dropId);
}
}

3. most important thing:
find this line in ext-all-debug.js : var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
in 3.2.1 which is line 20419.
change it to: var target = Ext.dd.DragDropMgr.getDDById(id);
the reason is the cachedTarget might give you same target twice. i enforce it find target every time.

hope this can help.

tomb@ibcos.co.uk
5 Nov 2010, 6:29 AM
I've just had this exact problem and found a simpler way of fixing it...

Simply alter the fireEvents function of Ext.dd.DragDropMgr at line 18981 in ext-all-debug.js (3.2.1) from

if (this.isOverTarget(pt, oDD, this.mode)) {
to

if (this.isOverTarget(pt, oDD, this.mode) && oDD.el && oDD.el.contains(e.getTarget())) {
This code now checks that the target element from the source mouse event is a child of the drop zone element before forwarding on a drop event.