aggregate1166877
aggregate1166877

Reputation: 3230

Getting hierarchical positions of <ul> and <li> in jquery

I'm trying to get how deeply nested my li's are using jquery, and then create a string containing the li's and numbers on how deeply they are nested. For example:

<ul>
    <li>
    MenuItem1
    </li>

    <li>
    MenuItem2
        <ul>
            <li>
            SubItemA
            </li>
        </ul>
    </li>

    <li>
    MenuItem3
    </li>
</ul>

should produce "0:MenuItem1 0:MenuItem2 1:SubItemA 0:MenuItem3" or at least something similar like that. Any ideas will be appreciated.

Upvotes: 4

Views: 1226

Answers (1)

Felix Kling
Felix Kling

Reputation: 817238

Something like:

var text = $('li').map(function() {
     var num_parents = $(this).parents('ul').length;
     // or .parentsUntil('#someId', 'ul') if you have `$('#someID li')` above
     return (num_parents - 1) + ': ' + $(this).contents().map(function() {
         if(this.nodeType === 3) {
             return $.trim(this.nodeValue);
         }
         return null;
     }).get().join('');
}).get().join(' ');

DEMO

Depending on your actual HTML structure, you can also simplify retrieving the text of a li element to

return (num_parents - 1) + ': ' + $.trim(this.firstChild);

if the text directly follows the opening <li> tag.

Or if you have other tags inside each li element (like span or div) and you want to get their content as well, you can clone the current node and remove all ul descendants:

var text = $.trim($(this).clone().find('ul').remove().end().text());
return (num_parents - 1) + ': ' + text;

Reference: map, parents, parentsUntil, contents, get

Upvotes: 5

Related Questions