views:

1041

answers:

2

Hello,

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!

+1  A: 

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.

karim79
If only it was that simple! Ha, That's what I get for trying to write an example on the spot. It's not an issue with the class names, as far as I can tell.
Davy
To be honest I'm pretty new to selectors, but I checked out the jquery API and they seem pretty straight forward. I set up a quick demo with your suggested changes here http://www.stiprojects.com/sortable.html. You can see how they just kind of slide together. Also what is a bit frustrating is that using "containment" makes it hard to swith the top and bottom listings.
Davy
A: 

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.

Davy