How do I programmatically abort a jQuery drag operation?
Using jQuery UI, the user begins a drag operation. While dragging, an asynchronous event occurs that causes the dragged element to be deleted (a timer-based refresh, for example). In the refresh, I would like to do something like this before the refresh to avoid errors from the deleted element :
element.trigger('dragstop');
But that didn't seem to work.
Officially cancelling a drag while dragging is not allowed in jQuery UI "by design"[1] -- I disagree with the situation, but it is as it is.
If you somewhat reliably want to cancel a drag mid-flight, you will need to combine a couple of hacks [2, 3]:
$( window ).keydown( function( e ){
if( e.keyCode == 27 ) {
var mouseMoveEvent = document.createEvent("MouseEvents");
var offScreen = -50000;
mouseMoveEvent.initMouseEvent(
"mousemove", //event type : click, mousedown, mouseup, mouseover, etc.
true, //canBubble
false, //cancelable
window, //event's AbstractView : should be window
1, // detail : Event's mouse click count
offScreen, // screenX
offScreen, // screenY
offScreen, // clientX
offScreen, // clientY
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
0, // button : 0 = click, 1 = middle button, 2 = right button
null // relatedTarget : Only used with some event types (e.g. mouseover and mouseout).
// In other cases, pass null.
);
// Move the mouse pointer off screen so it won't be hovering a droppable
document.dispatchEvent(mouseMoveEvent);
// This is jQuery speak for:
// for all ui-draggable elements who have an active draggable plugin, that
var dragged = $('.ui-draggable:data(draggable)')
// either are ui-draggable-dragging, or, that have a helper that is ui-draggable-dragging
.filter(function(){return $('.ui-draggable-dragging').is($(this).add(($(this).data('draggable') || {}).helper))});
// We need to restore this later
var origRevertDuration = dragged.draggable('option', 'revertDuration');
var origRevertValue = dragged.draggable('option', 'revert');
dragged
// their drag is being reverted
.draggable('option', 'revert', true)
// no revert animation
.draggable('option', 'revertDuration', 0)
// and the drag is forcefully ended
.trigger('mouseup')
// restore revert animation settings
.draggable('option', 'revertDuration', origRevertDuration)
// restore revert value
.draggable('option', 'revert', origRevertValue);
}
}
Now, this isn't pretty. But it works. Even when canceling while hovering an accepting droppable.
Have fun with it.
[1] - http://bugs.jqueryui.com/ticket/8414
[2] - https://gist.github.com/3517765
[3] - https://forum.jquery.com/topic/how-to-cancel-drag-while-dragging
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With