SlickNav jQuery plugin - only one open menu

4.6k Views Asked by At

I would like to achieve an accordion effect with this plugin. By default it works as a toggle. I would need to collapse opened menus when I click on another level 1 menu.

My structure is:

  • level 1 anchor
  • level 1 anchor

    • level 2 anchor
      • level 3 anchor
      • level 3 anchor
      • level 3 anchor
    • level 2 anchor
  • level 1 anchor

  • level 1 anchor

I need to close all opened level 1 submenus when I click on another submenu. Could anyone help me with this please?

Thank you very much.

I'm using this plugin - https://raw.github.com/ComputerWolf/SlickNav/master/jquery.slicknav.js

http://slicknav.com/

2

There are 2 best solutions below

0
On BEST ANSWER

this sems to work

$('#menu').slicknav({
    'open': function(trigger){
        var that = trigger.parent().children('ul');
        $('.slicknav_menu ul li.slicknav_open ul').each(function(){
            if($(this).get( 0 ) != that.get( 0 )){
                $(this).slideUp().addClass('slicknav_hidden');
                $(this).parent().removeClass('slicknav_open').addClass('slicknav_collapsed');
            }
        })
    }, 
});
0
On

I wanted the same functionality, but the accepted answer falls short. Among other things, it doesn't work if you have more than one level of menus. I modified the Plugin.prototype._itemClick function in the source to handle this in a better way. I would never want more than one menu open at the same level, but you could add a settings option to bypass my injected code. This modification will also ensure that your close handler is fired if you've added one. I've commented the code I added:

Plugin.prototype._itemClick = function (el) {
    var $this = this;
    var settings = $this.settings;
    var data = el.data('menu');
    if (!data) {
        data = {};
        data.arrow = el.children('.' + prefix + '_arrow');
        data.ul = el.next('ul');
        data.parent = el.parent();
        //Separated parent link structure
        if (data.parent.hasClass(prefix + '_parent-link')) {
            data.parent = el.parent().parent();
            data.ul = el.parent().next('ul');
        }
        el.data('menu', data);
    }

    if (data.parent.hasClass(prefix + '_collapsed')) {

        //  **** Begin custom code ****
        data.parent.siblings('.slicknav_open').each(function () {
            var $li = $(this);
            var $el = $li.children('a');
            var $ul = $el.next('ul');
            $el.children('.' + prefix + '_arrow').html(settings.closedSymbol);
            $li.addClass(prefix + '_collapsed').addClass(prefix + '_animating').removeClass(prefix + '_open');
            $this._visibilityToggle($ul, $li, true, $el);
        });
        //  **** End custom code ****

        data.arrow.html(settings.openedSymbol);
        data.parent.removeClass(prefix + '_collapsed');
        data.parent.addClass(prefix + '_open');
        data.parent.addClass(prefix + '_animating');
        $this._visibilityToggle(data.ul, data.parent, true, el);
    } else {
        data.arrow.html(settings.closedSymbol);
        data.parent.addClass(prefix + '_collapsed');
        data.parent.removeClass(prefix + '_open');
        data.parent.addClass(prefix + '_animating');
        $this._visibilityToggle(data.ul, data.parent, true, el);
    }
};

I hope this helps anybody else needing this functionality.