Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with nested jQuery sortables

Here's the basic HTML structure for my page:

<div id="selectedItemsTop">
    <ul>
        <li>
            Root element
            <ul>
                <li>Level One a</li>
                <li>Level One b</li>
                <li>
                    Level One parent
                    <ul>
                        <li>Level Two a</li>
                        <li>
                            Level Two parent
                            <ul>
                                <li>Level Three a</li>
                                <li>Level Three b</li>
                            </ul>
                        </li>
                        <li>Level Two b</li>
                    </ul>
                </li>
                <li>Level One c</li>
            </ul>
        </li>
    </ul>
</div>

eg:

  • Root element
    • Level One a
    • Level One b
    • Level One parent
      • Level Two a
      • Level Two parent
        • Level Three a
        • Level Three b
      • Level Two b
    • Level One c

There could be any number of items at each indentation level past the root, but there will only ever be 3 levels, and only one parent per level (ie: there's always exactly 3 <ul>s under the root, but the number of <li>s is variable).

I'm allowing the user to reorder this structure using the jQuery UI Sortable plugin. To add a new item, there are three groups of items (level one items, level two items, level 3 items) which sit adjacent on the page to this tree. The user can drag from there into the list to add it - but it must be added at the corresponding level.

I have this working already using draggable with the connectToSortable option:

$('ul.availableItems').each(function(i) {
    var selector = "#selectedItemsTop > ul";
    for (var j = 0; j <= i; ++j) { // count from 0 to [0, 1, 2]
        selector += " > li > ul";
    }
    // eg: selector == "#selectedItemsTop > ul > li > ul"
    // eg: selector == "#selectedItemsTop > ul > li > ul > li > ul"
    // eg: selector == "#selectedItemsTop > ul > li > ul > li > ul > li > ul"
    $(this)
        .find('li')
        .draggable({
            connectToSortable : selector
        })
    ;
});
$('#selectedFieldsTop > ul > li ul').sortable();

As I said, this works... in everything except IE. The level one items work perfectly, however no level 2 or 3 items will be added into the sortable. Trying to sort one of the Level 2 or 3 items which are already there makes it pick up the entire "Level One Parent" li and move the whole thing around.

Is there anything you could think of that would make this work in Firefox but not IE? Could you think of a different way to handle this?

Versions: Firefox 3.6, IE7, jQuery 1.3.2, jQuery UI 1.7.2

Update:
Here's the working code on JSBin: http://jsbin.com/ixabo/edit -- Unsurprisingly, it doesn't work in IE, but I think that's a problem with JSBin ("_console is undefined"). To see it half-working, perhaps copy/paste into a local file and open it in IE.

like image 811
nickf Avatar asked Feb 08 '10 07:02

nickf


2 Answers

Are you able to use other plugins? jsTree does this kind of thing very well.

like image 148
akiller Avatar answered Nov 07 '22 08:11

akiller


Also had problems with sortable earlier: my case was Accordion and sortables inside. I could not get a clear answer, but if you look at any of the tree implementations they are using drag-and-drop directly and not sortable.

Based on this experience - not very exact I know - I would agree with akiller and say: take a good tree plugin instead of trying to do this yourself with sortable. jsTree is quite good and should do the job - there are also others if for some reason jsTree does not suit your needs.

like image 33
Ope Avatar answered Nov 07 '22 08:11

Ope