jQuery Sortable how to set all children as a drop target

626 views Asked by At

I found this greate plugin: https://johnny.github.io/jquery-sortable/

I would like to have possibilty to drop daggable elements into every child. I've tried to do this adding an empty <ol></ol> but it dosnt work on run. I would have to do this before I build sortable tree. But I do everything dynamically.

And according to documentation:

name: drop
default: true
description: If true, items can be droped onto this container

So I understand that it should work that way out of the box?

Please help.

2

There are 2 answers

0
masterdany88 On BEST ANSWER

I figure it out.

The working solution:

$("ol.sortable").sortable({
  // animation on drop
  onDrop: function  (item, targetContainer, _super) {
    var clonedItem = $('<li/>').css({height: 0})
    item.before(clonedItem)
    clonedItem.animate({'height': item.height()})

    item.animate(clonedItem.position(), function  () {
      clonedItem.detach()
      _super(item)
    })
  }
})

I think that removing this fragment:

  group: 'simple_with_animation',
  pullPlaceholder: false,

from configuration helped.

1
MiKo On

Looks like nested lists work only when the li elements have a nested container (an ol or an ul) at the time the plugin is initialised.

You mentioned that you construct your tree dynamically. So, every time you add a new li in your tree, you will need to execute the following line to make the new node nestable:

$li.removeData('subContainers');

Only make sure the li has an ol or an ul, i.e.:

<ol class="sortable">
    ...
    <li>
        Your New Node
        <ol></ol>
    </li>
    ...
</ol>

Now, why exactly the line $li.removeData('subContainers'); works?
Looking inside the plugin code you might notice that when the plugin makes a decision whether to allow a drop inside a list item or not, it calls a method hasChildGroup (see line 506), which, in turn, calls another method getContainerGroup (see line 572), where it calculates and stores the information about the children, and possible drop targets of the node being hovered. The calculation happens only once and every subsequent drop attempt will reuse this data.

This is exactly what we should attack and erase this information from the node's data to make it re-calculate the data the next time.

'subContainers' is the key that the plugin uses to get the information and find a possible drop target. Therefore the entry with exactly this key should be removed from the node's data.