Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Drag In and Drag Out events #2198

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions src/Sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ let dragEl,
let ret;
sortables.some((sortable) => {
const threshold = sortable[expando].options.emptyInsertThreshold;

sortable[expando]._onDragLeave({
type: 'pointermove',
clientX: x,
clientY: y,
target: document.elementFromPoint(x, y),
rootEl: sortable
});

if (!threshold || lastChild(sortable)) return;

const rect = getRect(sortable),
Expand Down Expand Up @@ -403,6 +412,8 @@ function Sortable(el, options) {
!(name in options) && (options[name] = defaults[name]);
}

options._isHovered = false;

_prepareGroup(options);

// Bind all private methods
Expand Down Expand Up @@ -431,6 +442,7 @@ function Sortable(el, options) {
if (this.nativeDraggable) {
on(el, 'dragover', this);
on(el, 'dragenter', this);
on(el, 'dragleave', this);
}

sortables.push(this.el);
Expand Down Expand Up @@ -619,6 +631,7 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
});

on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
// on(ownerDocument, 'dragleave', nearestEmptyInsertDetectEvent);
on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);

Expand Down Expand Up @@ -720,6 +733,7 @@ Sortable.prototype = /** @lends Sortable.prototype */ {

if (this.nativeDraggable) {
on(document, 'dragover', _checkOutsideTargetEl);
// on(document, 'dragleave', _checkOutsideTargetEl);
}
let options = this.options;

Expand All @@ -731,6 +745,8 @@ Sortable.prototype = /** @lends Sortable.prototype */ {

fallback && this._appendGhost();

this.options._isHovered = true;

// Drag start event
_dispatchEvent({
sortable: this,
Expand Down Expand Up @@ -775,6 +791,18 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
if (inserted && !this.options.dragoverBubble) {
break;
}
} else {
// Is dragging over an element (var: target) that is not a Sortable container
// This element can be a child of the container or not
// This only works inside the window of the browser
// So moved outside of this if statement
/* parentEl[expando]._onDragLeave({
type: 'pointermove',
clientX: touchEvt.clientX,
clientY: touchEvt.clientY,
target: target,
rootEl: parent
}); */
}

target = parent; // store last element
Expand All @@ -783,6 +811,18 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
while (parent = parent.parentNode);
}

// I think the bug is because we tell the ParentEl to listen to the DragLeave
// but if we change too quickly of parent, then the ParentEl is another...
// so is never called and stays with the hover variable on true
// So moved to _detectNearestEmptySortable
/* parentEl[expando]._onDragLeave({
type: 'pointermove',
clientX: touchEvt.clientX,
clientY: touchEvt.clientY,
target: target,
rootEl: parent
}); */

_unhideGhostForTarget();
}
},
Expand Down Expand Up @@ -988,6 +1028,32 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
},


_onDragLeave: function (/**Event*/evt) {
var el = this.el,
target = evt.target,
options = this.options;

if (!options._isHovered) {
// console.log(`there was no hover in ${options.group.name}`)
return;
}
// console.log(`there was hover in ${options.group.name}`, evt)
if (
// ( evt.type == 'dragend' || evt.type == 'drop' ) || // from onDrop (makes no sense to trigger a drag-out on a drop event)
( evt.type == 'dragleave' && ( !el.contains(evt.relatedTarget) || !evt.relatedTarget) ) ||
( evt.type == 'pointermove' && ( !el.contains(target) || !target ) )
) {
options._isHovered = false;
_dispatchEvent({
rootEl: el,
name: 'dragOut',
originalEvent: evt
});
}

},


// Returns true - if no further action is needed (either inserted or another condition)
_onDragOver: function (/**Event*/evt) {
let el = this.el,
Expand Down Expand Up @@ -1119,6 +1185,17 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
dragOverEvent('dragOver');
if (Sortable.eventCanceled) return completedFired;

if ( !options._isHovered && !dragEl.contains(el)
&& activeSortable && !options.disabled
) {
options._isHovered = true;
_dispatchEvent({
rootEl: el,
name: 'dragIn',
originalEvent: evt
});
}

if (
dragEl.contains(evt.target) ||
target.animated && target.animatingX && target.animatingY ||
Expand Down Expand Up @@ -1321,6 +1398,7 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
off(document, 'touchmove', this._onTouchMove);
off(document, 'pointermove', this._onTouchMove);
off(document, 'dragover', nearestEmptyInsertDetectEvent);
off(document, 'dragleave', nearestEmptyInsertDetectEvent);
off(document, 'mousemove', nearestEmptyInsertDetectEvent);
off(document, 'touchmove', nearestEmptyInsertDetectEvent);
},
Expand All @@ -1339,6 +1417,8 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
let el = this.el,
options = this.options;

options._isHovered = false;

// Get the index of the dragged element within its parent
newIndex = index(dragEl);
newDraggableIndex = index(dragEl, options.draggable);
Expand Down Expand Up @@ -1489,6 +1569,23 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
newDraggableIndex = oldDraggableIndex;
}

sortables.some((sortable) => {

let x = (evt.changedTouches ? evt.changedTouches[0] : evt).clientX,
y = (evt.changedTouches ? evt.changedTouches[0] : evt).clientY,
elem = document.elementFromPoint(x, y);

if ( sortable.contains(elem) ) {
_dispatchEvent({
sortable: sortable[expando],
name: 'drop',
originalEvent: evt
});
return true;
}
return false;
});

_dispatchEvent({
sortable: this,
name: 'end',
Expand Down Expand Up @@ -1560,6 +1657,10 @@ Sortable.prototype = /** @lends Sortable.prototype */ {
}
break;

case 'dragleave':
this._onDragLeave(evt);
break;

case 'selectstart':
evt.preventDefault();
break;
Expand Down