I\'m experiencing a problem where the draggable helper is being offset incorrectly, when using draggables + sortables that are placed in floating, relative pos
What is strange is that it seems to work better with jquery-ui 10.4. The difference is that in 10.4 the draggable helper stays in its original div, and is cloned into the sortables but hidden. So calculations are easier to make.
In 11.4, the helper is appended to the sortable over which it is dragged, which makes the precise offset calculations hard to follow. You constantly have to change the parent offset, and keep track of over which sortable it is, over which sortable it was, the position of the sortable and so on. And clearly there is a bug there.
One simple solution would be to get the connectToSortable plugin from 10.4. You'll have to check for unwanted side effects, but quickly it seems to be working. You can use a different name so that you keep the original. Like this:
$.ui.plugin.add("draggable", "connectToSortable104", {
// You take the whole connectToSortable plugin from
// here: https://code.jquery.com/ui/1.10.4/jquery-ui.js
// In 11.4 you'll need to add draggable parameter
// for example: to the event methods,
// start: function(event, ui, draggable)
...
See http://jsfiddle.net/gsnojkbc/2/
EDIT:
I don't think the additional div is what causes the problem, it's really a bug with the way the connectToSortable works in jquery 11.4 that is causing the issue. To allow moving the helper in the sortables and still keep track of the proper offset, you need to readjust some data each time the helper changes div. There's two flaws in the way it's done:
First one is that there's a refreshOffsets method that is common to other events in draggable. It's used for example when you click on a draggable. And so it tries to calculate the offset based on the click. But when calling refreshOffsets from the sortable event, it messes the click offset. This can be solved by changing refreshOffsets method so as not to consider the event.pageX and Y. Like this:
$.ui.draggable.prototype._refreshOffsetsSortable = function(event, draggable){
this.offset = {
top: this.positionAbs.top - this.margins.top,
left: this.positionAbs.left - this.margins.left,
scroll: false,
parent: this._getParentOffset(),
relative: this._getRelativeOffset()
};
this.offset.click = draggable.offset.click;
}
The other problem happens because you have many sortables. Basically the other operation that needs to be done is change the parent offset. The way it's done right now is that it saves the previous parent. Normally it works but if you move too fast, the sequence makes it so that the saved parent is a sortable and not the original parent. You can fix this by saving the parent on drag start, which in any case makes seems to make more sense. Like this:
$.ui.plugin.add( "draggable", "connectToSortableFixed", {
start: function( event, ui, draggable ) {
var uiSortable = $.extend( {}, ui, {
item: draggable.element
});
draggable._parent = this.parent();
...
See here: http://jsfiddle.net/24a8q49j/1/