simon
simon

Reputation: 2377

jQuery menu tree, slide up/down

I'm trying to create a jQuery dropdow menu, so far it's working fine. Except that you can only open folders/trees, not close them again. I guess that i have to use EQ or Siblings in jQuery? But unfurtunately i don't know how to put them together - Could anyone show? :)

<ul class="nav">
    <li><a href="#">Test link</a></li>
    <ul class="nav">
        <li>Test under</li>
    </ul>
</ul>

jQuery(document).ready(function(){
    jQuery('.nav ul').css('display', 'none');

    jQuery('.nav li').click(function(){
        jQuery(this).find('ul:first').slideDown(); 
    })

})

//Simon

Upvotes: 0

Views: 4565

Answers (3)

FiLeVeR10
FiLeVeR10

Reputation: 2165

this should help

Each part is labeled, so it's easy to understand. This is much more aware and thought through than just using slideToggle. Instead it creates situations where it should slide up or down distinctly, and reverts previous branches when another is selected.

$('.nav ul').each(function () {
    $(this).on('click', function(e) {
        e.stopPropagation();//ignore ul clicks
    }).parent().on('click', function () {//target only parents of a ul
        if($(this).hasClass('on')) {//if selected
            $(this).addClass('on').children('ul').slideUp();//slideup
        } else {//if not selected
            if($(this).parent('.nav')) {//if start of branch
                $(this).parent().find('.on').removeClass('on').find('ul').slideUp();//close other branches
            }
            $(this).addClass('on').children('ul').slideDown();//slideDown
        }
    });
});

It's recursive, and it only targets li that have a ul child. When you select a different branch it will also revert the previously opened branch. I removed the anchor tags, because the action was to be on click, and the links in the example didn't go anywhere. If it doesn't go anywhere, why does it need to have a link?

It also fixes the html formatting, to put the uls inside of the lis, instead of them being siblings. ie <li><ul><li></li></ul></li> instead of <li></li><ul><li></li></ul>.

made a fiddle: http://jsfiddle.net/filever10/gmL4x/

Upvotes: 1

Terry
Terry

Reputation: 66093

There is a syntax error with your markup - the only valid direct descendant of a <ul> element is <li>. If you want to nest your list, do it within the <li> itself:

<ul class="nav">
    <li>
        <a href="#">Test link</a>
        <ul class="nav">
            <li>Test under</li>
        </ul>
    </li>
</ul>

For toggling, we simply instruct to search for a sibling <ul> element and apply the .slideToggle() method to it when the link is clicked:

$(function() {
    // Hide submenus
    $(".nav ul").hide();

    // Toggle nested <ul> (siblings of the link)
    $(".nav > li > a").click(function(e) {
        $(this).siblings("ul").slideToggle();
        e.preventDefault();
    });
});

Here is a demo fiddle: http://jsfiddle.net/teddyrised/2y9fz/ (added more list items to demonstrate the effect)

Upvotes: 2

Marcel Puyat
Marcel Puyat

Reputation: 325

Use slideToggle(); instead of slideDown();, this will make it so it performs slideDown or slideUp depending on the current orientation.

Upvotes: 1

Related Questions