Question

I have created a nested list with drag/drop functionality. My issue is that I want each nesting to sort in itself. For example:

-first_level
-first_level
 -second_level
 -second_level
-first_level

"First level" should not be able to go into "Second Level" and vice versa. I thought I could do this with the containment option but no dice there. It works with keeping the second levels out of the first level but not the other way around.

Here is my example JS and list:

$("#sort_list").sortable({
  containment: '#sort_list',                                             
  axis: 'y',
  revert: true,
  items: 'li',
  opacity: 0.8
});
$(".sub_list").sortable({ 
  containment: 'parent',
  axis: 'y',
  revert: true,
  items: 'li',
  opacity: 0.8,
});
$("#sort_list").disableSelection();

<ul id="sort_list">
  <li>one</li>
  <li>two
    <ul class="sub_list">
    <li>sub one</li>
    <li>sub two</li>
    </ul>
  </li>
  <li>three</li>
  <li>four</li>
</ul>   

Any ideas? Thanks guys!

Was it helpful?

Solution 2

Okay, looks like I found the problem. I was declaring: items: 'li' and so it wasn't detecting the UL as a container/sortable item. A big thanks to karim79 for helping me think all this through :)

Below is the working code (it's basically saying "Everyone stay in their own container"):

    $("#sort_list").sortable({
      containment: 'parent',                                                                                     
      axis: 'y',
      revert: true,
      opacity: 0.8
    });
    $(".sub_list").sortable({ 
      containment: 'parent',
      axis: 'y',
      revert: true,
      opacity: 0.8,
    });
    $("#sort_list").disableSelection();

    <ul id="sort_list">
      <li>one</li>
      <li>two
        <ul class="sub_list">
        <li>sub one</li>
        <li>sub two</li>
        </ul>
      </li>
      <li>three</li>
      <li>four</li>
    </ul>

Now that we got the "item: li" thing sorted out we can even remove containment: 'parent', from the top list without fear of the lists colliding.

OTHER TIPS

Try giving the containment option a complex selector like:

$("#sort_list").sortable({
  containment: '#sort_list:not(.sub_list)',                                                                                     
  axis: 'y',
  revert: true,
  items: 'li',
  opacity: 0.8
});

That should do the trick if you're using jQuery 1.3+:

(from the manual)

As of jQuery 1.3 :not() also support selectors separated by commas and complex selectors, for example: :not(div a) and :not(div,a).

The jQuery Sortable manual says the containment option:

Constrains dragging to within the bounds of the specified element - can be a DOM element, 'parent', 'document', 'window', or a jQuery selector.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top