tags:

views:

239

answers:

4

I'm trying to make a menu that collapses, markup is below:

Whenever a .cat_menu_header is clicked, the ul below it should expand and all expanded ul's should collapse. So we start with everything collapsed and only the .cat_menu_header elements visible, with max 1 .submenu being expanded at one time.

<ul id='sidebarNav'>
  <li class='cat_menu_header'><a class='collapsed' href='#'>Link 1
    <ul class='submenu'>
      <li><a href='#'>text 1</a></li>
      <li><a href='#'>text 2</a></li>
    </ul>
  </li>
  <li class='cat_menu_header'><a class='collapsed' href='#'>Link 2
    <ul class='submenu'>
      <li><a href='#'>text 3</a></li>
      <li><a href='#'>text 4</a></li>
    </ul>
  </li>
</ul>

The follow js makes each .submenu expand and collapse but I can't figure out how to select all expanded ul's and collapse them. I added the .collapsed class which could be changed to .expanded with toggleClass.

I know I'm close ...

    $(document).ready(function(){ 
 //sidebar collapsible menu
 $("#sidebarNav > li > ul").hide();

 $("#sidebarNav a.collapsed").click(function() {
  $(this).toggleClass("expanded").toggleClass("collapsed").find("+ ul").slideToggle("fast");
  return false;
 });
});
A: 

Bear with me as my brain is a bit fried and I can't think of the specific code, but I'd be inclined to hide/collapse all elements and then only expand $(this) when 'a.collapsed' is clicked. Hope that makes sense :)

$(document).ready(function(){       
//sidebar collapsible menu
$("#sidebarNav > li > ul").hide();

$("#sidebarNav a.collapsed").click(function() {
 $("#sidebarNav > li > ul").slideUp('fast'); // Slide them all up
 $(this).toggleClass("expanded").toggleClass("collapsed").find("+ ul").slideToggle("fast");
 return false;
});

});

Dan
works for me, thanks!
stef
actually ... clicking an open menu closes it and opens it again. not quite there
stef
A: 

So what I do for this is make a reference to the CURRENT clicked item:

var $this = $(this);

Then close ALL links:

$('.submenu').hide();

Then open the one you want:

$this.show()

This should get you moving in the right direction. It's also probable that for this kind of operation you should NOT be using "toggle" as it will be a major PITA. Just use click(), close everything, open the clicked one after everything has been closed.

Jason
Why would toggle be a major PITA?
stef
A: 
function helper(ele) {
    ele.toggleClass("expanded")
       .toggleClass("collapsed")
       .find("+ ul")
       .slideToggle("fast");
}
$("#sidebarNav a.collapsed").live("click", function() {
    //just close the ones which are open
    helper($("ul#sidebarNav a.expanded"));
    helper($(this));
    return false;
});
jitter
this works, except when you click the link above an ul that's already open, it collapses and opens again. Ideally it would just collapse
stef
Check again. Slightly modified. `.click(function() ...` replaced with `.live("click", function() ...`
jitter
+1  A: 

First, your "li.cat_menu_header a" tag are not closed.

<ul id="sidebarNav">
    <li class="cat_menu_header collapsed">
        <a href="#">Link 1</a>
        <ul class="submenu">
            <li><a href="#">text 1</a></li>
            <li><a href="#">text 2</a></li>
        </ul>
    </li>

    <li class="cat_menu_header collasped">
        <a href="#">Link 2</a>
        <ul class="submenu">
            <li><a href="#">text 1</a></li>
            <li><a href="#">text 2</a></li>
        </ul>
    </li>
</ul>

It is easier to flag the li.cat_menu_header with the collasped or expanded class in order to use siblings() function. That is useful if you want to keep your actions relative to the context, for instance if you initialize this event for more than one sidebar.

jQuery( function()
{
    $("#sidebarNav ul.submenu").hide();

    $("#sidebarNav li.cat_menu_header > a").click( function()
    {
        $(this).parent().siblings( ".expanded" ).addClass( "collapsed" ).slideUp( "fast" );
        $(this).parent().addClass( "expanded" ).removeClass( "collapsed" );
        $(this).next().slideDown( "fast" );
    } );
} );

This example make the "li.cat_menu_header a" just expand its "submenu".

Ploufka