Search and Top Navigation
#6259 open bug ()
Opened November 03, 2010 04:11PM UTC
Last modified March 05, 2019 05:49AM UTC
Droppable: drop event incorrectly triggered when dragging a draggable over a droppable onto a sortable
Reported by: | avuori | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 2.0.0 |
Component: | ui.droppable | Version: | 1.8.6 |
Keywords: | Cc: | avuori | |
Blocked by: | Blocking: |
Description
When a draggable is connected with a sortable, and there is also a droppable involved, the droppable's drop event is erroneously triggered when the draggable is dragged quickly over the droppable (without ever releasing the mouse).
The example demonstrates the problem. It may not be reproducible instantly, but a few down/up drag movements should do it. An alert is shown when the droppable event is triggered.
The problem seems to be present only when the draggeble's helper is "clone".
<html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.js"></script> </head> <body> <script> $(function() { $("tbody.sortable").sortable({}); $(".draggable").draggable({ helper: "clone", connectToSortable: "tbody.sortable" }); $(".droppable") .droppable({drop: function () { alert("dropped"); } }); $("td").disableSelection(); }); </script> <table> <tbody> <tr class="draggable ui-state-highlight"><td>Drag me down above the sortable, then quickly drag me up directly over and past the droppable</td></tr> <tr class="droppable ui-state-highlight"><td>Droppable</td></tr> </tbody> <tbody class="sortable"> <tr class="ui-state-default"><td>Item 1</td></tr> <tr class="ui-state-default"><td>Item 2</td></tr> <tr class="ui-state-default"><td>Item 3</td></tr> <tr class="ui-state-default"><td>Item 4</td></tr> <tr class="ui-state-default"><td>Item 5</td></tr> </tbody> </table> </body> </html>
Attachments (1)
Change History (13)
Changed November 03, 2010 04:28PM UTC by comment:1
Changed December 31, 2010 02:08AM UTC by comment:2
I had the same issue on my site with very different markup. Was also using clone.
Changed March 12, 2011 10:46PM UTC by comment:3
_comment0: | $(".droppable") \ .droppable({drop: function () { \ if (!$(event.srcElement).hasClass("ui-draggable-dragging")) { return; } \ alert("dropped"); \ } \ }); \ \ will be solve your problem → 1299970024519568 |
---|---|
_comment1: | $(".droppable") \ .droppable({drop: function () { \ if (!$(event.srcElement).hasClass("ui-draggable-dragging")) { return; } \ \ alert("dropped"); \ } \ }); \ \ will be solve your problem → 1551764970286114 |
$(".droppable") .droppable({drop: function () { if (!$(event.srcElement).hasClass("ui-draggable-dragging")) { return; } alert("dropped"); } });
will be solve your problem
Changed March 15, 2011 04:28PM UTC by comment:4
_comment0: | Replying to [comment:3 cnr]: \ > $(".droppable") \ > .droppable({drop: function () { \ > if (!$(event.srcElement).hasClass("ui-draggable-dragging")) { return; } \ > \ > alert("dropped"); \ > } \ > }); \ > \ > will be solve your problem \ \ \ Thanks for the tip! \ → 1551764987537961 |
---|
Replying to [comment:3 cnr]:
... will be solve your problem
Thanks for the tip!
Changed October 11, 2012 09:07PM UTC by comment:5
milestone: | TBD → 2.0.0 |
---|
Changed October 29, 2012 04:21AM UTC by comment:6
status: | new → open |
---|---|
summary: | Droppable's drop event triggered when dragging a draggable over the droppable → Droppable: drop event incorrectly triggered when dragging a draggable over a droppable onto a sortable |
confirmed on latest: http://jsfiddle.net/2aJh9/
Changed July 25, 2013 10:33AM UTC by comment:7
Because I needed the droppable to be droppable I fixed it by handling the drop event in the draggable:
var draggableOnDroppable; .droppable({ over: function(event,ui) { draggableOnDroppable = true; }, out: function(event, ui) { draggableOnDroppable = false; }); .draggable({ stop: function (event, ui) { if (draggableOnDroppable) //do something with draggable } });
Changed October 11, 2013 05:49PM UTC by comment:8
Is there a known workaround?
Is there an alternative to using clone helper?
Changed October 11, 2013 05:53PM UTC by comment:9
Is there a known workaround?
Is there an alternative to using clone helper?
Changed March 22, 2014 09:01AM UTC by comment:10
_comment0: | Hello, the solution is simple. The drop can't be effective if you don't release the left mouse, so just detect the state of it, and bloc any action in droppable if you don't have left mouse released : \ \ \ var leftButtonDown; \ $(document).mousedown(function(e){ \ if(e.which === 1) leftButtonDown = true; \ }); \ $(document).mouseup(function(e){ \ if(e.which === 1) leftButtonDown = false; \ }); \ \ .droppable({ \ drop:function(e,ui){ \ \ if(leftButtonDown) return false; \ // Here code when really drop \ \ }); → 1551764956663020 |
---|
Hello, the solution is simple. The drop can't be effective if you don't release the left mouse, so just detect the state of it, and bloc any action in droppable if you don't have left mouse released :
var leftButtonDown; $(document).mousedown(function(e){ if(e.which === 1) leftButtonDown = true; }); $(document).mouseup(function(e){ if(e.which === 1) leftButtonDown = false; }); .droppable({ drop:function(e,ui){ if(leftButtonDown) return false; // Here code when really drop });
Changed July 09, 2014 10:22AM UTC by comment:11
_comment0: | Replying to [comment:10 paulf66]: \ > Hello, the solution is simple. The drop can't be effective if you don't release the left mouse, so just detect the state of it, and bloc any action in droppable if you don't have left mouse released : \ > \ > \ > var leftButtonDown; \ > $(document).mousedown(function(e){ \ > if(e.which === 1) leftButtonDown = true; \ > }); \ > $(document).mouseup(function(e){ \ > if(e.which === 1) leftButtonDown = false; \ > }); \ > \ > .droppable({ \ > drop:function(e,ui){ \ > \ > if(leftButtonDown) return false; \ > // Here code when really drop \ > \ > }); \ \ \ This work-around works perfectly for FF & Chrome but IE10 triggers drop event first and then mouseup will get fire. So again this will not work on IE10. \ → 1551764939277841 |
---|
Replying to [comment:10 paulf66]:
Hello, the solution is simple. The drop can't be effective if you don't release the left mouse, so just detect the state of it, and bloc any action in droppable if you don't have left mouse released : ...
This work-around works perfectly for FF & Chrome but IE10 triggers drop event first and then mouseup will get fire. So again this will not work on IE10.
Changed April 01, 2015 06:51PM UTC by comment:12
_comment0: | I was able to find a quick workaround for those who are still interested. \ \ Basically the problem occurs only when during the drag over the sortable your draggable is in the position when its both over the droppable and sortable (highlighting both). \ \ Feel free to add a quick data() or just a flag to your ui.helper during the out() of the sortable which could be removed during the over() of the droppable. \ PS Make sure you don't allow your drop() on droppable to execute first time after the sortable out()! \ \ Example: \ \ self.contentTemplate.sortable({ \ ... bla bla bla ... \ out: function (event, ui) { \ // workaround for bug http://bugs.jqueryui.com/ticket/6259 \ ui.helper.data('overSortable', true); \ }, \ ... bla bla bla ... \ }); \ \ template.droppable({ \ ... bla bla bla ... \ over: function (event, ui) { \ // workaround for bug http://bugs.jqueryui.com/ticket/6259 \ ui.helper.removeData('overSortable'); \ }, \ drop: function (event, ui) { \ // workaround for bug http://bugs.jqueryui.com/ticket/6259 \ if (ui.helper.data('overSortable') != null) { \ ui.helper.removeData('overSortable'); \ return; \ } \ ... bla bla bla ... DO THE STUFF \ }, \ ... bla bla bla ... \ }); \ \ \ → 1427914440031696 |
---|---|
_comment1: | I was able to find a quick workaround for those who are still interested. \ \ Basically the problem occurs only when during the drag over the sortable your draggable is in the position when its both over the droppable and sortable (highlighting both). \ \ Feel free to add a quick data() or just a flag to your ui.helper during the out() of the sortable which could be removed during the over() of the droppable. \ PS Make sure you don't allow your drop() on droppable to execute first time after the sortable out()! \ \ Example: \ \ self.contentTemplate.sortable({ \ ... bla bla bla ... \ out: function (event, ui) { \ // workaround for bug http://bugs.jqueryui.com/ticket/6259 \ \ ui.helper.data('overSortable', true); \ }, \ ... bla bla bla ... \ }); \ \ template.droppable({ \ ... bla bla bla ... \ over: function (event, ui) { \ // workaround for bug http://bugs.jqueryui.com/ticket/6259 \ \ ui.helper.removeData('overSortable'); \ }, \ drop: function (event, ui) { \ \ // workaround for bug http://bugs.jqueryui.com/ticket/6259 \ \ if (ui.helper.data('overSortable') != null) { \ ui.helper.removeData('overSortable'); \ return; \ } \ ... bla bla bla ... DO THE STUFF \ }, \ ... bla bla bla ... \ }); \ \ \ → 1551764920664269 |
I was able to find a quick workaround for those who are still interested.
Basically the problem occurs only when during the drag over the sortable your draggable is in the position when its both over the droppable and sortable (highlighting both).
Feel free to add a quick data() or just a flag to your ui.helper during the out() of the sortable which could be removed during the over() of the droppable.
PS Make sure you don't allow your drop() on droppable to execute first time after the sortable out()!
Example:
self.contentTemplate.sortable({ ... bla bla bla ... out: function (event, ui) { // workaround for bug http://bugs.jqueryui.com/ticket/6259 ui.helper.data('overSortable', true); }, ... bla bla bla ... }); template.droppable({ ... bla bla bla ... over: function (event, ui) { // workaround for bug http://bugs.jqueryui.com/ticket/6259 ui.helper.removeData('overSortable'); }, drop: function (event, ui) { // workaround for bug http://bugs.jqueryui.com/ticket/6259 if (ui.helper.data('overSortable') != null) { ui.helper.removeData('overSortable'); return; } ... bla bla bla ... DO THE STUFF }, ... bla bla bla ... });
Changed May 12, 2015 10:24AM UTC by comment:13
I think I've pieced together which bits of code are interacting to cause this, plus also for "deactivate" to be triggered on droppables when you just drag a draggable back out of a connected sortable. The "drag" handler of the draggable's "connectToSortable" plugin has a bit which says:
// If it doesn't intersect with the sortable, and it intersected before, // we fake the drag stop of the sortable, but make sure it doesn't remove // the helper by using cancelHelperRemoval.
When you drag a draggable into a sortable and then out again as you drag out of the sortable that bit of code triggers and part of it calls:
sortable._mouseStop( event, true );
The _mouseStop of sortable then in turn runs this bit of code:
//If we are using droppables, inform the manager about the drop if ($.ui.ddmanager && !this.options.dropBehaviour) { $.ui.ddmanager.drop(this, event); }
So it will call drop on the ddmanager, which doesn't seem desirable and can have two side effects.
The first is the one mentioned on this ticket - if your draggable happens to have moved over a droppable as you've moved out of the sortable then you'll see the drop event trigger (ddmanager.drop will check if the draggable intersects with a droppable and only call drop if it has).
The second one is one which prompted me to dig into this stuff which is that dragging a draggable into a sortable and then out of a sortable again will result in _deactivate being called on any droppables on the page:
this._deactivate.call( this, event );
I spotted this because I was using the activeClass option of a droppable to highlight it where my draggable was also connected to a sortable. I was finding that dragging the droppable into and out of the sortable was causing the highlighting to go off.
This fiddle demonstrates:
http://jsfiddle.net/k0w71yb1/2/
On that fiddle drag the draggable downwards slowly and you'll see the drop area will highlight as you begin to drag. Continue to drag the draggable down through the sortable list and then out below the sortable list. You'll see that the highlighting of the drop area will cease and a "deactivate" will be logged to the console. Then stop dragging (let go of the mouse button) and you'll see a second "deactivate" will be logged to the console.
I would guess the fix could be for _mouseStop to be told that it's a fake drag stop and know to not trigger the "drop" event on the droppables in this circumstance, but I don't know enough about why the code is doing what it's doing to be sure!
Tested with Chrome and Firefox 3.6.