0

EDIT
I improved the answer and created a blog post about it here.


I followed this post in order to add the jQuery accordion functionality to the Quick Launch in SharePoint.
While the code in the above link applies to SharePoint 2007, I somewhat managed to change it so that it should now work with SharePoint 2013.

Here's the code that I currently have:

///<reference path="jquery-1.2.6-vsdoc.js"/>
function initQuickLaunch() {
    // For each Quick Launch navigation link (sub menu): 
    $("ul#zz16_RootAspMenu>li.static>ul.static>li.static>a.static").each(function(){
        // Find any navigation items under the sub menu that have been selected.
        var selectedNavItems = $(this).find("a.selected");

        // Find the corresponding heading of the current sub menu being processed
        var menuHeader = $(this).parents("a:eq(0)").prev("a").find("ul#zz16_RootAspMenu>li.static>a.static:eq(0)");         

        if ($(menuHeader).hasClass("selected") || selectedNavItems.length > 0) 
        {
            // If the navigation header for this sub menu is selected or if there are any 
            // selected navigational items in this submenu, show the submenu.
            $(this).show();
            // alert('Show submenu');
        }
        else
        { 
            // otherwise, hide the submenu
            $(this).hide();
            // alert('Hide submenu');
        }
    });

    // When a user clicks a navigation heading, the user should be taken directly
    // to the corresponding page of that subsite. The javascript event handler to 
    // hide/display the submenus should not be triggered.
    $("ul#zz16_RootAspMenu>li.static>a.static").click(function(e) {
        e.stopPropagation();
        // alert('User clicked on navigation header');   
    });

    // When the user hovers over the navigation heading, it would be nice
    // to have an indicator that they can click on the heading. Usually,
    // browsers use the hand icon to indicate clickable items.
    $("ul#zz16_RootAspMenu>li.static>a.static").hover(function(e){
        $(this).css("cursor", "hand");
    }, function(e){
        $(this).css("cursor", "default");
    });

    //Finally, this adds a click event handler for the navigation heading 
    $("ul#zz16_RootAspMenu>li.static>a.static").click(function(e) { 
        var subMenu = $(this).parents("a:eq(0)").next("a").find("ul#zz16_RootAspMenu>li.static>ul.static>li.static>a.static:eq(0)");
        // alert(subMenu.length);
        if (subMenu.length > 0)
        {
            //only if we have a submenu should we hide the other submenus and show the current one.
            $("ul#zz16_RootAspMenu>li.static>ul.static>li.static>a.static").hide("slow");
            subMenu.show("slow");

        }
    });
};

Currently the above code can hide all the navigation links under each heading in the Quick Launch upon load, but the problem I have is: when you click on a certain heading, it does not show the corresponding navigation links. It just follows the url behind that heading and goes to that subsite. And when it is on the subsite, it should normally show all the navigation links underneath that subsite as well, but this doesn't work either.

You may see some alerts in comment here and there, I just added those to see which part of the code gets executed when I test it out.

I would really appreciate it if someone would take a look at this, I'm sure I'm just looking over something small, I just can't figure out what.

Steps to reproduce:
1) Copy the above code and paste it in a new file named "accordion.js"
2) Add a reference to this file in your master page (see code below for my reference)

<script src="/Style Library/Intranet/scripts/accordion.js" type="text/javascript"></script>

3) Change the body tag on the master page (see code below)

<body onload="initQuickLaunch()">

4) Test it out on a site that uses that master page

Thanks for your time!

3 Answers 3

2

You cannot use scripts created for a SharePoint 2007 masterpage in SharePoint 2013 - I guess there are way too many differences.

I found a solution for SharePoint 2013 (code is in english): http://joao-pinho.blogspot.de/2012/11/sharepoint-2013-accordion-quicklaunch.html?m=1

$(function(){
 /*set dynamic css logic*/
 if($('#sideNavBox .menu-item.selected').length){
  //propagates the selected class, up the three.
  $('li.static').removeClass('selected');
  $('#sideNavBox .menu-item.selected').parents('li.static').addClass('selected');

  //collapses top siblings of selected branch
  $('#sideNavBox .menu-item.selected').parents('li.static').last().siblings()
   .find('> ul').hide();
 }
 else $('#sideNavBox .root.static > li.static > ul').hide();

 /*set accordion effect*/
 $('#sideNavBox .root.static > li.static').each(function(){
  if($(this).find('ul').length){
   $(this).addClass('father').click(function(){
    if($(this).children('ul').css('display') != 'none'){
     $(this).removeClass('selected').children('ul').slideUp();
    }
    else {
     /*collapse-siblings*/
     $(this).siblings().removeClass('selected').children('ul').slideUp();

     /*expand*/
     $(this).addClass('selected').children('ul').slideDown();
    }

    return false; //**<= add this one**
   });
  }
 });
});
2
  • This one does seem to work, but as soon as I click a heading it still follows the link behind it. It does show the sub menu for a very short moment tho. Any idea how to fix this?
    – Magali
    Mar 12, 2013 at 14:30
  • This is a sign that there is a return false; missing for the click event. I fixed it in the answer above. Mar 13, 2013 at 15:55
0

There is a bug in the solution above (sub links do not work) that is fixed with this solution: http://borderingdotnet.blogspot.com/2013/04/accordion-left-navigation-for.html

0

Above code wont work properly if you click on submenus.working code is below

<script type="text/javascript">
        $(function () {
            /*set dynamic css logic*/
            if ($('#sideNavBox .menu-item.selected').length) {
                //propagates the selected class, up the three.
                $('li.static').removeClass('selected');
                $('#sideNavBox .menu-item.selected').parents('li.static').addClass('selected');

                //collapses top siblings of selected branch
                $('#sideNavBox .menu-item.selected').parents('li.static').last().siblings()
                 .find('> ul').hide();
            }
            else $('#sideNavBox .root.static > li.static > ul').hide();

            /*set accordion effect*/
            $('#sideNavBox .root.static > li.static').each(function () {
                if ($(this).find('ul').length) {
                    $(this).children('span').addClass('father').click(function () {
                        if ($(this).parent().children('ul').css('display') != 'none') {
                            $(this).parent().removeClass('selected').children('ul').slideUp();
                        }
                        else {
                            /*collapse-siblings*/
                            $(this).parent().siblings().removeClass('selected').children('ul').slideUp();

                            /*expand*/
                            $(this).parent().addClass('selected').children('ul').slideDown();
                        }

                        /*added: stop event propagation to link nodes*/


                        /*added*/
                        return false;
                    });
                }
            });
        });

    </script>
1
  • This works great! Thanks a lot. I would just like to ask for a little comment: How to avoid the "blink" effect. When loading the page the quick launch appears opened by default and as soon as the code is run (around half a second later) the menu is collapsed. What can I do to make sure this code runs before it is displayed to avoid this effect? Jun 14, 2016 at 8:21

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.