I've a sortable element inside another sortable element. Both are connected to each other. Following the the sample markup:
<div id='container'>
<div class='parent'>
<div class='child'>1</div>
<div class='child'>2</div>
<div class='child'>3</div>
<div class='child'>4</div>
</div>
<div class='parent'>
<div class='child'>5</div>
<div class='child'>6</div>
<div class='child'>7</div>
<div class='child'>8</div>
</div>
</div>
What i'm trying to do is to drag multiple items between .parent
's and #container
.
Following is the JS:
$("#container").on('click', '.child', function () {
$(this).toggleClass('selected');
});
$('.parent').sortable({
appendTo: "#container",
connectWith: '.parent, #container',
revert: 0,
helper: function (e, item) {
if (!item.hasClass('selected')) {
item.addClass('selected').siblings().removeClass('selected');
}
var elements = $('#container').find('.selected').clone();
$('#container').find('.selected').not(item).addClass('hidden');
var helper = $('<div/>', {
class: 'parent'
});
return helper.append(elements);
},
start: function (e, ui) {
var len = ui.helper.children().length;
var width = ui.item.width() + 2;
ui.helper.width((len * width));
ui.placeholder.width((len * width));
},
stop: function (e, ui) {
$('.selected').removeClass('selected');
}
});
$('#container').sortable({
connectWith: '.parent',
tolerance: "pointer"
});
The following
with the whole code (I removed the code for appending items to minimize the code since that is not relevant to the placeholder position) demonstrates the issue i'm facing:
I'm able to drag items from .parent
to the #container
as follows:
#container
as shown below:
#container
through the space between .parents
(This is a bit tricky but it works when the center is exactly hovered over the space) as shown below:
But Once i drag an item outside, the placeholder does not appear to the right side of #container
even when i directly hover the item over it.
Expected output:
Current result:
As shown in the image, the placeholder is inside the .parent
even though the item is away from it, inside #container
.
From what i tried, the issue is with the following:
$('#container').find('.selected').not(item).addClass('hidden');
Where i hide the selected items using display:none
, Possibly causing miscalculations with jQuery UI.
So i tried refresh and refreshPositions in the start event, as in this JSFiddle, Which is produces the expected output, but it no longer properly displays the placeholder in #container
in the other two scenario.
What i want to do is to be able to drag items from .parent
to #container
by
#container
#container
through the space between .parents
#container
Side note: Most of the sortable options are added while trying to fix the issue, and the css dimensions are for demo purpose only, these can be added or removed if necessary.
Update: this seems like a bug, which i reported here. The jQuery UI team replied that they are in the process of rewriting all interactions. So hopefully this will be fixed in the next release.
In my code, it has almost become a convention to just apply this poorly documented hack to Sortable’s over
and out
callback functions:
if($.ui.ddmanager.current)
$.ui.ddmanager.prepareOffsets($.ui.ddmanager.current, null);
This will make sure positions are refreshed, and in contrast to the built-in refresh
and refreshPositions
methods, it seems to work.
Could you try this approach, and see if it improves your Sortable’s behavior?
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