Thomaszter
Thomaszter

Reputation: 1474

How to number nested li's in jquery

I try do number all links in a nested list, the number should go in the "data-nav-no" attribute, the result should be like this:

<ul class="mainNav">
    <li><a href="#startseite" data-nav-no="1">Startseite</a></li>
    <li><a href="#ueber-uns" data-nav-no="2">Über uns</a></li>
    <li><a href="#leistungen" data-nav-no="3">Leistungen</a>
        <ul class="subNav">
            <li><a href="#langfristige-unterstuetzung" data-nav-no="4">Langfristige Unterstützung</a></li>
            <li><a href="#punktuelle-unterstuetzung" data-nav-no="5">Punktuelle Unterstützung</a></li>
        </ul>
    </li>
    <li><a href="#referenzen" data-nav-no="6">Referenzen</a></li>
    <li><a href="#news" data-nav-no="7">News</a></li>
    <li><a href="#kontakt" data-nav-no="8">Kontakt</a></li>
</ul>

I tried this:

$("ul.mainNav li, ul.subNav li").each(function() {
    var index = $(this).index();    
    $(this).children("a").attr('data-nav-no',index);
});

Works, but in the second list level the number starts with "0" again. Any ideas to solve that?

Upvotes: 1

Views: 599

Answers (2)

Matt
Matt

Reputation: 75317

The following should do what you want:

$("ul.mainNav li").each(function(i) {
    $(this).children("a").attr('data-nav-no',i)
});

The selector ul.mainNav li is finding all lis that are descendants of ul.mainNav; which includes the elements matched by the selector ul.subNav li. This is why I've omitted the ul.subNav li selector from my example. If you want to only target the children of the ul.mainNav element, then you should use the child selector instead of the descendant:

$("ul.mainNav > li, ul.subNav > li").each(function(i) {
    $(this).children("a").attr('data-nav-no',i)
});

The .index() method you were using returns the position of the element relative to it's sibling elements, where-as the index parameter provided by .each() is the position of the element in the jQuery collection.

Upvotes: 4

Jon
Jon

Reputation: 437376

A simple change will be enough:

$("ul.mainNav, ul.subNav").find("li").each(function(index) {
    $(this).children("a").attr('data-nav-no',index)
});

The important detail is that you don't want to try to compute the index yourself, but just use what each passes into your callback function.

See it in action (the example changes the HTML to make the results visible).

Upvotes: 3

Related Questions