views:

1902

answers:

1

I have nested sortable list that can have items dynamically added or removed and can be nested n-levels deep. On nesting, a new ul element is injected into whatever li element is selected to be the parent. The initial state of the list is something like the following:

<ul id="parent">
    <li id="One"><a href="" class="listLink"><span class="position">1</span>One</a></li>
    <li id="Two"><a href="" class="listLink"><span class="position">2</span>Two</a></li>
    <li id="Three"><a href="" class="listLink"><span class="position">3</span>Three</a>
     <ul>
      <li id="A"><a href="" class="listLink"><span class="position">1</span>A</a></li>
      <li id="B"><a href="" class="listLink"><span class="position">2</span>B</a></li>
      <li id="C"><a href="" class="listLink"><span class="position">3</span>C</a></li>
      <li id="D"><a href="" class="listLink"><span class="position">4</span>D</a></li>
      <li id="E"><a href="" class="listLink"><span class="position">5</span>E</a></li>
      <li id="F"><a href="" class="listLink"><span class="position">6</span>F</a></li>     
     </ul>
    </li> 
    <li id="Four"><a href="" class="listLink"><span class="position">4</span>Four</a></li>
    <li id="Five"><a href="" class="listLink"><span class="position">5</span>Five</a></li>
    <li id="Six"><a href="" class="listLink"><span class="position">6</span>Six</a></li>     
</ul>

I'm using MooTools to do the sort, etc and it works fine, but what I'm having trouble doing is resetting the position text correctly on sort. Every CSS selector I try to use also includes all of the children rather than just the li elements that belong in the list and not any belonging to sublists. Assume that except for id, position, and text, each li element in all lists is identical to all others. Is there a selector for getting only the immediate children? Is there another way to do this?

Edit:

I've tried some child selectors like the ones mentioned:

  • "ul > li" Will select all li elements that are a child of a ul, not just the immediate children
  • "#parent > li" Does the same as above.

Edit 2:

Here is the function that I'm currently having run when an item is dropped (this doesn't handle the sorting, which works fine, just updating the position). Note that it is also MooTools syntax:

var drop = function(el){
    el.getParents('ul').reverse().each(function(item){
     var posCount = 1;
     item.getElements('li a span[class=position]').each(function(pos){
      pos.set('text', posCount);
      posCount++;
     });
    });
}

Currently, changing any item order on the main level will renumber everything 1-12, even the sublists. Changing any item on a sublist will give the correct numbers for that list, but cause the parent lists to incorrectly count all child li elements in numbering.

Edit 3:

Okay, I feel like this is an ugly hack, but it works.

var drop = function(){
    var ulCount = 1;
    $$('ul').each(function(item){
     if(item.get('id') != 'parent') { 
      item.set('id', 'id-'+ulCount);
     }
     var elId = item.get('id');
     var posCount = 1;
     $(document).getElements('#'+elId+'>li>a>span[class=position]').each(function(pos){
      pos.set('text', posCount);
      posCount++;
     });
     ulCount++;
    });
}
+8  A: 
ul > li

only does the immediate children. So, for example, to do only the top level list elements you could use:

#parent > li

Note: this isn't supported on IE6.

The common workaround for backwards compatibility is to do something like this:

#parent li { /* style appropriately */ }
#parent li li { /* back to normal */ }

It's more tedious because you have to apply styles and then turn them off (and you may not necessarily know what the old values are) but it's only only IE6 pure CSS workaround there is.

Edit: Ok you have a MooTools specific issue. getElements() returns all descendants, not just immediate children. Try using getChildren().

var drop = function(el){
    el.getParents('ul').reverse().each(function(item){
        var posCount = 1;
        item.getChildren('li").getElements("a span[class=position]").each(function(pos){
                pos.set('text', posCount);
                posCount++;
        });
    });
}

or something like that.

cletus
Thanks, but MooTools handles the IE6 issue, so that's not quite what I'm after. I'm looking for a way to reset the text of the spans to indicate the correct position for that list, but not parent or child lists, which is where the problem is coming in.
VirtuosiMedia
#parent > li absolutely only does the immedate children. You have something else going on if thats not working. More information is probably required.
cletus
MooTools lets me use CSS3 selectors, but because I haven't been able to change only the immediate children, it incorrectly changes the numbers for all my sublists as well.
VirtuosiMedia
It's probably worth posting a code snippet.
cletus
I posted a snippet above.
VirtuosiMedia
Thanks for the help. I ended up doing something similar.
VirtuosiMedia