1

I'm attempting to create a vertical accordion menu for a website I'm working on. This is my first time ever doing anything with jquery. I've been able to get a working menu the way I want it, except for a couple of things.

1) I need a menu that will stay expanded based on which page is loaded, if you click on an item inside the second menu, then the second menu needs to be expanded when the page is reloaded. The menu doesn't stay expanded when you click and load a new page from within the menu. Upon page reload, it just completely collapses until you click on a header to expand it again. I've been searching online for days and can't find anything that I can use to solve this problem. I've looked at using the jquery cookie plugin and just checking to see which page is currently loaded and using that to determine which menu needs to be expanded, but I can't get either of them to work.

2) My menu only expands when clicked, it doesn't collapse when clicked again. Is it possible to collapse the same menu you just expanded by clicking again?

Here's the js file I created:

function initMenu() {
    $('#menu ul').hide();
    $('#menu li a').click(function () {
        var checkElement = $(this).next();
        if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
            $(this).siblings().removeClass("selected");
            return false;
        }
        if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
            $('#menu ul:visible').slideUp('normal');
            checkElement.slideDown('normal');
            if (!$(this).hasClass("selected")) {
                // Remove the class from anything that is active
                $("a.selected").removeClass("selected");
                // And make this active
                $(this).addClass("selected");
            }
            return false;
        }
    });
}
$(document).ready(function () {
    initMenu();
});

Here's a jsfiddle for full html and css as well: http://jsfiddle.net/CShsY/

Thanks.

Thomas Spade
  • 724
  • 6
  • 11
  • 25
  • 1
    Maybe checkout a plugin that has those options already built out for you. http://webcloud.se/jQuery-Collapse/ – ferne97 Apr 29 '13 at 21:08

6 Answers6

2

I've updated your fiddle: http://jsfiddle.net/CShsY/4/

It's got a lot of general improvements and also fixes your second problem. Your initMenu() function now looks like this:

function initMenu() {
    $('#menu li > a').click(function(e){

        if($(this).next('ul').length > 0){

            e.preventDefault();

            var subNav = $(this).next('ul');

            if (subNav.is(':visible')){
                subNav.slideUp('normal')
                $(this).removeClass("selected");
            }else{
                $('#menu ul:visible').slideUp('normal');
                subNav.slideDown('normal');
                $("a.selected").removeClass("selected");
                $(this).addClass("selected");
            }
        }

    });
}

e.preventDefault() just prevents the default action of the a. I've also added a check in there so any a elements which don't have a ul after them will still work as regular links.

For your first problem you might want to take a look at this question: highlight the navigation menu for the current page. The answer was basically to add a class or id to your body element which uniquely identifies the page as well as adding classes to each of your menu links. For example:

<body id="home">
    /* other code here */
    <ul id="menu">
        <li><a href="#">Menu 1</a>
            <ul class="home">
            /* more code here */

CSS:

#home #menu ul.home{display:block}
/* The sub menu of 'home' will show on the home page */
Community
  • 1
  • 1
Joe
  • 15,205
  • 8
  • 49
  • 56
0

I'm not sure if this is the best way to do it, but I added the following line, just after the opening of the click function:

if ($(this).is(':visible')) {$('#menu ul:visible').slideUp('normal')};

So the full code reads:

function initMenu() {  
    $('#menu ul').hide();  
    $('#menu li a').click(function () {  
        if ($(this).is(':visible')) {$('#menu ul:visible').slideUp('normal')};  
        var checkElement = $(this).next();  
        if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {  
            $(this).siblings().removeClass("selected");  
            return false;
        }
        if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
            $('#menu ul:visible').slideUp('normal');
            checkElement.slideDown('normal');
            if (!$(this).hasClass("selected")) {
                // Remove the class from anything that is active
                $("a.selected").removeClass("selected");
                // And make this active
                $(this).addClass("selected");
            }
            return false;
        }
    });
}
$(document).ready(function () {
    initMenu();
});
KevinD
  • 3,023
  • 2
  • 22
  • 26
0

Use Jquery accordion plugin

To achieve the first functionality use option active

To achieve the second functionality use option collapsible

NullPointerException
  • 3,732
  • 5
  • 28
  • 62
0

I can answer point 2)

You need to add a slideUp function when the element you click has a visible UL as it's next element.

i.e.

if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
    $(this).siblings().removeClass("selected");
    checkElement.slideUp('normal');
    return false;
 }
Dan
  • 184
  • 5
0

I used the code you kindly provided here (tried implementing them all one by one to my accordion list), but the thing is that the parent list item becomes a dead link when it collapses and opens its sublist. Is there a way to make it a link, so when i click on a link item that has the sub list, it opens its page, but also keeps the submenu open?

astronaut
  • 33
  • 1
  • 5
0

Try this solution which work for both highlighting the selected menu item and slide control based on selected menu.

Select menu function is placed in master page

<script type="text/javascript">
    function SelectMenu(index) {
        var accordion_head = $('.sidebar-menu > li');
        var main = accordion_head[index];
        $(main).addClass("active");
        $(main).find('a').next().slideDown(200);
    }
</script>

In each page listed in accordian menu, specify the below

<script type="text/javascript">
    $(document).ready(function () {
        SelectMenu(1);
    });
</script>
Pranesh Janarthanan
  • 1,134
  • 17
  • 26