Esc to abort drag?
Right now there seems to be no way to cancel dragging an element. If the user started to drag an item and changed their mind, they have to remember where the element started from, and drag it back there. Esc just drops the element, as does releasing the mouse button.
Would it be more useful if Esc aborted the drag operation and animated the element back in its original place?
Have to think, it sounds reasonable.
Kendo UI Core Sortable has a nice implementation of this feature.
https://github.com/RubaXa/Sortable/blob/master/Sortable.js#L514 needs to be modified like this:
else if (dragEl.nextSibling !== nextEl && evt.dataTransfer.dropEffect !== 'none') {
// Update event if element was dragged, and Esc was not pressed
...undo drag code here?...
- The element is already moved.
- If it is a touch-device:
evt.dataTransfer === undefined
Well yes, on a touch device you can't press Esc. What would be the code to move the element back? Seems like onStart should store the start position (prevSibling || nextSibling), then onEnd would move the element to that stored start position, after prevSibling (unless it was the first element) or before nextSibling otherwise.
Well yes, on a touch device you can't press Esc. What would be the code to move the element back? Seems like onStart should store the start position (prevSibling || nextSibling), then onEnd would move the element to that stored start position, after prevSibling (unless it was the first element) or before nextSibling otherwise.
Looking forward for this. Any ETA @owen-m1 ?
I've written a plugin to support this feature. Have a look:
/**
* Returns the CancelSort Sortable
* Plugin, to cancel a drag action
* by hitting the ESC key.
*
* @returns {Function}
*/
export function CancelSortPlugin() {
function CancelSort() {
this.defaults = {
cancelSort: true,
revertOnSpill: true
};
}
CancelSort.prototype = {
drop({ cancel, dispatchSortableEvent, originalEvent, dragEl, cloneEl }) {
// In case the 'ESC' key was hit,
// the origEvent is of type 'dragEnd'.
if (originalEvent.type === 'dragend') {
// Call revert on spill, to revert the drag
// using the existing algorithm.
this.sortable.revertOnSpill.onSpill(...arguments);
// Undo changes on the drag element.
if (dragEl) {
// Remove ghost & chosen class.
dragEl.classList.remove(this.options.ghostClass);
dragEl.classList.remove(this.options.chosenClass);
dragEl.removeAttribute('draggable');
}
// In case of a copy, the cloneEl
// has to be removed again.
if (cloneEl) {
cloneEl.remove();
}
// Dispatch 'end' event.
dispatchSortableEvent('end');
}
}
}
return Object.assign(CancelSort, {
pluginName: 'cancelSort'
});
}
And make use of it like this:
import Sortable from 'sortablejs';
import { CancelSortPlugin } from './path/to/plugin/sortable-cancel-plugin.js';
Sortable.mount(CancelSortPlugin());
This will cancel (or revert) d&d when the user hits 'ESC', even if the object was already inserted in another list. Disabling this plugin during runtime is not possible, but can be easily added.
Still no official change or fix for this yet?