2

I want to achieve something similar like the question How to convert unordered list into nicely styled dropdown using jquery?, but with a hierarchical ul list. I want to convert this HTML:

<ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About us</a>
        <ul>
            <li><a href="/about/staff">Staff</a></li>
                <ul>
                    <li class="current-page"><a href="/about/staff/john-doe">John Doe</a></li>
                    <li><a href="/about/staff/jane-doe">Jane Doe</a></li>
                </ul>
        </ul>
    </li>
    <li><a href="/products">Products</a>
        <ul>
            <li><a href="/products/games">Games</a>
                <ul>
                    <li><a href="/products/games/xbox">XBOX</a></li>
                    <li><a href="/products/games/ps3">PlayStation 3</a></li>
                    <li><a href="/products/games/ipad">iPad</a></li>
                    <li><a href="/products/games/iphone">iPhone</a></li>
                </ul>
            </li>
            <li><a href="/products/hardware">Hardware</a>
                <ul>
                    <li><a href="/products/hardware/controllers">Controllers</a></li>
                    <li><a href="/products/hardware/memory">Memory units</a></li>
                </ul>
            </li>
            <li><a href="/products/upcoming">Upcoming</a></li>
        </ul>
    </li>
    <li><a href="/contact">Contact us</a></li>
</ul>

To this:

<select>
    <option value="/">Home</option>
    <option value="/about">About us</option>
    <option value="/about/staff">- Staff</option>
    <option value="/about/staff/john-doe" selected>-- John Doe</option>
    <option value="/about/staff/jane-doe">-- Jane Doe</option>
    <option value="/products">Products</option>
    <option value="/products/games">- Games</option>
    <option value="/products/games/xbox">-- XBOX</option>
    <option value="/products/games/ps3">-- PlayStation 3</option>
    <option value="/products/games/ipad">-- iPad</option>
    <option value="/products/games/iphone">-- iPhone</option>
    <option value="/products/hardware">- Hardware</option>
    <option value="/products/hardware/controllers">-- Controllers</option>
    <option value="/products/hardware/memory">-- Memory</option>
    <option value="/products/upcoming">- Upcoming</option>
    <option value="/contact">Contact us</option>
</select>

The class "current-page" on the li should mark the corresponding option in the select as selected. A jQuery as well as vanilla JavaScript would do.

3
  • To clarify: The ul list can have more than three levels in its hierarchy so there shouldn't be any limit to that. Commented Sep 12, 2011 at 9:06
  • Have you tried anything yet? please post your code sample. Commented Sep 12, 2011 at 9:07
  • Have you tried starting with the script from the question you linked with a slightly different selector? If you make your selector select all li elements that are descendants of your root ul then put them in a list then that should do the trick mostly... Commented Sep 12, 2011 at 9:08

1 Answer 1

5

Here's some jQuery code doing what you want. As I don't know where you want the <select> appended, I'm just appending it directly to <body>. There's also an issue of the $('li') selector being too greedy (it will select all <li> elements in the document), but it's easy to fix given the knowledge about the parent elements of the <ul> element you've posted.

(function($) { $(function() {
    var $select = $('<select>')
        .appendTo('body');

    $('li').each(function() {
        var $li    = $(this),
            $a     = $li.find('> a'),
            $p     = $li.parents('li'),
            prefix = new Array($p.length + 1).join('-');

        var $option = $('<option>')
            .text(prefix + ' ' + $a.text())
            .val($a.attr('href'))                       
            .appendTo($select);

        if ($li.hasClass('current-page')) {
            $option.attr('selected', 'selected');
        }
    });
});})(jQuery);

I would also consider using <optgroup> instead of the - prefix as a way of indicating the hierarchy level.

Sign up to request clarification or add additional context in comments.

1 Comment

wow, this is brilliant. I also added the snippet from here to go to the URL on change: stackoverflow.com/a/5150486/819276 Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.