Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery ui sortable inaccurate placeholder placement in nested sortables

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

JSFiddle

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:

  • By dragging the items to the left of #container as shown below: enter image description here
  • By dragging items above #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: enter image description here

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:

desired outpuy

Current result:

current output

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

  1. Dragging items to the left of #container
  2. Dragging items above #container through the space between .parents
  3. Dragging items to the right of #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.

like image 973
T J Avatar asked Aug 31 '14 18:08

T J


1 Answers

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?

like image 157
Hein Haraldson Berg Avatar answered Oct 24 '22 18:10

Hein Haraldson Berg