ngDraggable
ngDraggable copied to clipboard
ng-drop on overlapping dropzones should only fire one drop event.
I created a small pen to verify this behavior.
HTML 5 drag and drop API : If I drop a draggable object onto an area that has overlapping drop zones, only one drop will be fired. I assume its the drop for the highest stacked element.
ngDraggable API : 2 drop events will be fired. I don't believe that this the desirable behavior?
I think i found a solution, in ngDrop directive hitTest function :
var hitTest = function(x, y) {
var bounds = element[0].getBoundingClientRect();// ngDraggable.getPrivOffset(element);
x -= $document[0].body.scrollLeft + $document[0].documentElement.scrollLeft;
y -= $document[0].body.scrollTop + $document[0].documentElement.scrollTop;
var draggingElmt = document.getElementsByClassName("dragging")[0];
var display = draggingElmt.style.display;
draggingElmt.style.display = 'none';
var isTopElement = document.elementFromPoint(x, y) == element[0] || element[0].contains( document.elementFromPoint(x, y) );;
draggingElmt.style.display = display;
return x >= bounds.left
&& x <= bounds.right
&& y <= bounds.bottom
&& y >= bounds.top && isTopElement;
};
I have tested this and it works nicely. Will do some further testing based on my requirements and confirm. Thanks for the great work.
Worked perfectly. Tested using z-index to define the window stacking order
pull request - https://github.com/fatlinesofcode/ngDraggable/pull/224
well I hit this one as well. I made 3 changes. hope it helps :)
- comment out the isTouching here, It slowed things down badly for me
var onDragMove = function(evt, obj) {
if(! _dropEnabled)return;
// isTouching(obj.x,obj.y,obj.element);
if (attrs.ngDragMove) {
$timeout(function(){
onDragMoveCallback(scope, {$data: obj.data, $event: obj});
});
}
};
- passed in the dragElement[0] to hitTest
var isTouching = function(mouseX, mouseY, dragElement) {
var touching= hitTest(mouseX, mouseY, dragElement[0]);
scope.isTouching = touching;
if(touching){
_lastDropTouch = element;
}
updateDragStyles(touching, dragElement);
return touching;
};
-
new hitTest
var hitTest = function(x, y,dragElement) { var bounds = element[0].getBoundingClientRect();// ngDraggable.getPrivOffset(element); x -= $document[0].body.scrollLeft + $document[0].documentElement.scrollLeft; y -= $document[0].body.scrollTop + $document[0].documentElement.scrollTop; //var draggingElmt = document.getElementsByClassName("dragging")[0]; var display = dragElement.style.display; dragElement.style.display = 'none'; var isTopElement = document.elementFromPoint(x, y) == element[0] || element[0].contains( document.elementFromPoint(x, y) );; dragElement.style.display = display; return x >= bounds.left && x <= bounds.right && y <= bounds.bottom && y >= bounds.top && isTopElement; };
I got the same issue, the reason is, the drop area div's are overlapping on each other so if we drop item for one time, the item got place on 2 divs's; It got resolved by separating 2 div's;
Thanks
after updated the hitTest code,that issue resolved But drag drop is very slow due to that code. can you please look on that..