views:

115

answers:

2

Hi, I'm trying to take a structure of nested html unordered lists as a database for some information a need to organize and analyze. I'm trying to filter, count and present the information using jQuery. I'm striving for the lists not to have any class or id attribute, so that they are very clean. Only the root would have a class or id like this:

<ul id="root">
<li> First first-level element
  <ul>
    <li> First second-level element
      <ul>
        <li>First Third-level element</li>
        <li>Second Third-level element</li>
      </ul>
    </li>
    <li> Second second-level element
      <ul>
        <li>Third Third-level element</li>
        <li>Fourth Third-level element</li>
      </ul>
    </li>
  </ul>
</li>
<li> Second first-level element
  <ul>
    <li> Third second-level element
      <ul>
        <li>Fifth Third-level element</li>
      </ul>
    </li>
  </ul>
</li>
</ul>

My question is: how can I select a li's immediate child text node without selecting text in that li's child and grandchild ul's (i.e. its sublists)? For example, given the html list above, I would like to be able to come up with a list of all text nodes in the second level:

  • First second-level element
  • Second second-level element
  • Third second-level element

Or all text from the third level... etc. That would allow me to list and count the items in a given level. The closest I've been is:

// to select items in second but not third level
$('ul#root ul').not('ul#root ul ul').children('li')  

But it is not a flexible solution. What if the list has many levels, say seven? to select sixth level you would have to do something like:

// to select items in second but not third level
$('ul#root ul ul ul ul ul').not('ul#root ul ul ul ul ul ul').children('li')  

There must be another way but I haven't found it. Any suggestions are much appreciated.

A: 

If you want to select second li eg <li> Second second-level element, you can use the > child selector with eq like this:

$('ul#root > ul > li').eq(1)

For the third you set eq to 2 because its indexing starts from 0.

To loop over them, you can use the each like this:

$('ul#root > ul > li').eq(1).each(function(){
  alert($(this).text());
});

More Info:

Sarfraz
It doesn't work. Also, a li was missing in the selector. If I add the li: $('ul#root > li > ul > li').eq(1).each(function(){ alert($(this).text());});I still get all of the text within the li's children uls. I guess that's because the li actually has the child uls when you get it at the "each" loop. I'll try to get it inside the loop. Any other idea? Thank you.
Froilan
A: 

As stated here:

http://stackoverflow.com/questions/1023199/jquery-find-the-text-of-a-list-item-that-contains-a-nested-ul/2662066#2662066

"Normal DOM methods allow to access text contents for just one element"

So this is one solution: This outputs third level elements one by one:

$('ul#root > li > ul > li > ul').children('li').each(function(){
  alert($(this)[0].firstChild.textContent);
});

This outputs second level elements:

$('ul#root > li > ul').children('li').each(function(){
  alert($(this)[0].firstChild.textContent);
});

This outputs first level elements:

$('ul#root').children('li').each(function(){
  alert($(this)[0].firstChild.textContent);
});
Froilan