Opened 4 years ago

Last modified 2 years ago

#13024 new bug

draggable with connectToSortable not compatible with clone helper

Reported by: esion Owned by:
Priority: minor Milestone: none
Component: ui.sortable Version: 1.11.4
Keywords: Cc:
Blocked by: Blocking:

Description

The dragged item is not removed from DOM when sortable use helper clone

how to reproduce : http://plnkr.co/edit/Bc98fE0yAgf3aQtJDmep?p=preview

  1. Move an item from 3rd list (draggable) to any position
  2. move an item from 1rst list to the second one

the old item is frozen in front at the place it was dropped

Note: 1rst & 2 nd list are sortables but I also see it on a droppable

the config used in plnkr :

$(function() {
  $( "#sortable1, #sortable2" ).sortable({
    connectWith: ".connected",
    helper: "clone",
  }).disableSelection();
  
  $("#clonnable1 li").draggable({
    connectToSortable: "#sortable1, #sortable2"
  }).disableSelection();
});

This is due to : sortable.cancelHelperRemoval = true in "stop" callback : https://github.com/jquery/jquery-ui/blob/1.11.4/ui/draggable.js#L762

Change History (4)

comment:1 Changed 4 years ago by esion

eventually a screenshot

https://drive.google.com/file/d/0BzN06uJT7FrLSnRzX1JHUXhYems/view

comment:2 Changed 3 years ago by Scott González

Component: ui.coreui.sortable

comment:3 Changed 3 years ago by jcano

Is there any progress on this? I can confirm this is happening:

http://jsfiddle.net/jcano/nqk15c02/

Same steps to reproduce:

  1. Drag from the first list (draggable) to any of the sortables
  2. Drag from the other sortable to the first sortable.

The helper is not removed, it stays visible at the last position before releasing the mouse button. This is due to how draggable manages dropping on a connected sortable. It sets the variable cancelHelperRemoval to true on the sortable but never returns the value to false, so the sortable from that point on will never remove helpers.

comment:4 Changed 2 years ago by matt-hoskins

This bug is still present in 1.12.1 - I've just hit this same bug myself. I've updated the jsfiddle from jcano to reference 1.12.1:

http://jsfiddle.net/nqk15c02/3/

The cause is still the same.

The issue was introduced in 1.11.2 as a side effect of this commit:

https://github.com/jquery/jquery-ui/commit/1cc380778b99c87acc82f363f6376d11d4d3759a

However I don't understand what this setting "this.instance.cancelHelperRemoval = true" is actually achieving (other than introducing this bug). This particular piece of code is called in cases where "sortable.isOver" is not true - which I presume means that the draggable isn't within this connected sortable at this point? In which case even if this draggable had entered that sortable at some point, it must have exited it already and thus connectToSortable's drag event would have already called _mouseStop on the sortable (and _mouseStop is the only place for sortable where cancelHelperRemoval on the sortable is used). The next line after setting this.instance.cancelHelperRemoval = true is to trigger "deactivate" on the sortable which, as far as I can tell, doesn't result in a call on _mouseStop (and _mouseStop won't be called on that sortable because isOver is not true).

The comment in the code says "Prevent this Sortable from removing the helper" - as per my reading of the code noted above I don't believe a sortable with isOver not being true will remove the helper because it's not due to have _mouseStop called by this point.

I believe that cancelHelperRemoval on the sortable is purely for use by connectToSortable's drag, when the draggable is dragged out of a sortable, to signal to that sortable's _mouseStop code that it shouldn't remove the helper (because the drag is still in progress of course). I think the code in connectToSortable's ".stop" to set cancelHelperRemoval is purely to clean up any cancelHelperRemoval values left to true. What should probably happen really is that after connecToSortable's ".drag" calls sortable._mouseStop it should then revert sortable.cancelHelperRemoval back to false to clean up after itself as, as far as I can tell, it doesn't need to be left set to true. If ".drag" did reset cancelHelperRemoval back to false then ".stop" for connectToSortable doesn't need to touch cancelHelperRemoval at all on the sortables - if sortable.isOver is true then the current code allows the sortable to do the helper removal so it can be left as false, and on ones where isOver is false then _mouseStop isn't going to be called on them so they're not going to try remove the helper anyway.

Of course I'm no expert in jqueryui code, this is just me trying to piece together what happens, so maybe I've made a mistake :).

Note: See TracTickets for help on using tickets.