Article
68 comments

Build a flexible mega drop down navigation for SharePoint

I’ve read a lot of good articles about mega menus or mega drop in the past. They all were from a technical point of view correct and useful introduction about the basics behind. When it comes to SharePoint you should always consider the user and how they can administer or change the design on their own. This is one of the strengths in SharePoint and the user should always be in the center of every solution. For a mega menu it doesn’t take much to accomplish. This can be done easily in SharePoint Designer or Visual Studio. Choose your weapon of choice and spend 30 Minutes to build up a simple but powerful mega menu.

The ingredients and how they work together

In general a mega menu is nothing more than an HTML Snippet that will be loaded when a user hover over a navigation item. This can be the top navigation or in SharePoint terms the quick launch navigation. For embedding to the quick launch the code only needs to be slightly changed.

The base of the mega menu is a customized article page that has a web part zone for the drop down content. The navigation is the out of the box navigation that should be extended for the following tasks

  • Hover over a navigation item
  • Grab the link URL
  • Load the linked page
  • Cut out the required web part zone
  • Add it to the page as the content of the mega drop down

To accomplish those tasks the well-known JavaScript library Jquery will be used.

The article page

In general to define the content of the mega menu any mega menu can be used as a starting point. The only thing that needs to be done is to encapsulate any web part zone into a <div> element.

Mockup Mega Drop Down Article Page

Mockup Mega Drop Down Article Page

The code for this is simple and looks like this:

...
<ContentTemplate>
 <div class="article article-right">
 <PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel">
 <SharePointWebControls:TextField runat="server" FieldName="Title"/>
 </PublishingWebControls:EditModePanel>
 <div class="n8d-dropdown" id="megadropdownitem">
 <WebPartPages:WebPartZone runat="server" AllowPersonalization="false" ID="TopZone" FrameType="None" Title="<%$Resources:cms,WebPartZoneTitle_Top%>" Orientation="Vertical" />
 </div>
</ContentTemplate>
...

 

The script that performs the mega menu magic will simply grab the defined <div> element with all the content in it and adds it to the navigation. Then the author will be able to add content to their demand or change existing content without any single line of code. The only thing that needs to be defined is styled to show the content in a proper way.

The master page

The second thing that is required for this solution is a master page. This is only needed to register the required styles and Jquery scripts. In the default configuration of the master page SharePoint already have a fly out navigation.

....
 <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.2.min.js" type="text/javascript"></script>
 <script src="/_layouts/n8d.MegaMenu/MegaMenu.js" type="text/javascript"></script>
 <link type="text/css" href='/_layouts/n8d.MegaMenu/MegaDropDown.css' rel="stylesheet" />
...

To avoid possible conflicts with the script, the navigation control needs to be modified. This can be done by changing the properties for the MaximumDynamicDisplayLevels. It needs to be set from the default value which is 1 and needs to be set 0. This means that no dynamic children will be rendered.

...
<asp:ContentPlaceHolder id="PlaceHolderHorizontalNav" runat="server">
 <SharePoint:AspMenu
 ID="TopNavigationMenuV4"
 Runat="server"
 EnableViewState="false"
 DataSourceID="topSiteMap"
 AccessKey="<%$Resources:wss,navigation_accesskey%>"
 UseSimpleRendering="true"
 UseSeparateCss="false"
 Orientation="Horizontal"
 StaticDisplayLevels="2"
 MaximumDynamicDisplayLevels="0"
 SkipLinkText=""
 CssClass="s4-tn" />
   <SharePoint:DelegateControl runat="server" ControlId="TopNavigationDataSource" Id="topNavigationDelegate">
     <Template_Controls>
       <asp:SiteMapDataSource
        ShowStartingNode="False"
        SiteMapProvider="SPNavigationProvider"
        id="topSiteMap"
        runat="server"
        StartingNodeUrl="sid:1002"/>
     </Template_Controls>
   </SharePoint:DelegateControl>
</asp:ContentPlaceHolder>
...

Now that the base setup is done it’s time for some JQuery magic.

The Mega Menu Script

As mentioned before the script doesn’t do much. So when the page is loaded JQuery grabs all URL from the top navigation and looks for content that should be added to the navigation. This will be done by inserting a new <div> element directly on every item of the top navigation. This will be done by the following function.

var loadingData = function(){

    var navigationElement = $(this);
    var link = $(this).attr("href");
    var text = $(this).find(".menu-item-text").text();
    $(this).attr("linkname", text);

    $.ajax({
            url: link,
            async: false,
            dataType: "html",
            success: 
                function (data) {
                    content = $(data).find("#megadropdownitem");
                    
                    if(content.html() != undefined){
                        // fix content for calender
                        content.find(".ms-WPBody").each(function () {
                            $(this).removeAttr("webpartid");
                            $(this).removeAttr("class");
                            $(this).removeAttr("id");
                        })
                        newContent = "<div class='mdd-itemcontent'><div class='mdd-innercontent'>"+content.html()+"</div></div>";
                        navigationElement.parent().prepend(newContent);
                    }
                }
    });

}

For the animation of the flyout i simply added a hover binding to all of the navigation items.

$(document).ready(function(){

    var pageMode = $("#MSOSPWebPartManager_DisplayModeName");

    if(pageMode.val() == "Browse"){
        $(".s4-tn li.static a.static").each(loadingData);
        $(".s4-tn li.static").hover(showFlyOut, hideFlyOut);
    }
});

var showFlyOut = function(){
    if($(this).children(".mdd-itemcontent").html() != null){
        $(this).children(".menu-item").toggleClass("hover");
        $(this).children(".mdd-itemcontent").slideDown("fast");
    }
}

var hideFlyOut = function(){
    if($(this).children(".mdd-itemcontent").html() != null){
        $(this).children(".menu-item").toggleClass("hover");
        $(this).children(".mdd-itemcontent").slideUp("fast");
    }
}

The functions showFlyout and hideFlyout will show and hide the mega menu / flyout and also the class of the current selected navigation item will be toggled for a better styling. The last step was to add the design for the menu. After that the mega menu looks like this.

Finished look of the mega drop down

Finished look of the mega drop down

Let me show you how the solution works in the following video.

How to create a mega menu navigation in SharePoint from Stefan Bauer on Vimeo.

As seen in the solution the content of the mega drop down is flexible. Static or dynamic content can be added without changing the core functionality. No server side code is required, which makes it easy to adapt for SharePoint 2013. By changing the style sheets the form of the drop down can be easily adapted. While I used visual studio to deploy my solution this functionality can be added by using SharePoint Designer too. I think the most time consuming task in my mega menu solution are the design adoption but a simple drop down menu can be accomplished in 30 minutes. Would be great if you can share your experience with my solution. Finally what’s left to say have fun in creating you own variations.

Update Nov 19, 2013: Bugfix Calendar Web Part

As David Foster and Scott McLeod pointed out in the comments there is an error when a calendar will be used. The items were delegated to the mega menu instead of the list web part. The solution below is updated and contains the fixed version.

Download Visual Studio Solution

68 Comments

  1. Stefan:

    This is nice work. I’ve done something similar, using jQuery to AJAX in the megamenu content, with the added wrinkle of having personalized links coming in based on User Profile data. I’d love to compare notes with you.

    M.

    Reply

    • Marc, thank you for your feedback. It would be great if we can share our experiences with mega menus.

      /greetings
      Stefan

      Reply

  2. Interesting approach using a web part holding data for the navigation. But I really like the way using ajax to fetch data from an url to get the appropriate data for the mega menu in the current context. Gives me lots of ideas how to create mega menu data.. maybe not a web part but something else.. 🙂 .. let’s see ..

    Going to SPC by the way ? (stupid question)

    Reply

  3. Very nice. Really like the way this enables easy maintenance of the dropdown content for site managers. And as you said: because of it’s flexibility, it allows easy migration to SharePoint 2013 where you can to things like add a Content Search Web Part to personalize the dropdown.

    One question: how did you deal with the link in the menuitem which leads to the menucontent page? Did you simply disable it with jQuery?

    Reply

    • Well actually you can disable the links with JQuery or leave it active. It depends on how you like it. I prefer to leave the links active because i can use the pages for additional content too. Content that won’t be displayed in the drop down and create landing pages.
      If you like to disable the links all you need to do is add the following inside the document ready function.
      $(".s4-tn li.static a").click(function(event){ event.preventDefault(); });
      I think it should work. You will find the documentation in the Jquery documentation: http://api.jquery.com/event.preventDefault/

      Reply

    • The core solution allows a lot of interpretations and enhancements 😉
      It’s a nice plugin in you found here. Thanx for sharing.

      Reply

  4. Hi Stefan,

    This looks amazing. However I am having a bit of trouble.. I would appreciate it if you could help me out.
    Do I just drop the DropDown.aspx into the site pages in Sharepoint designer? And the master page into the master pages in designer? I uploaded the CSS and script to my _layouts folder. I don’t see the navigation dropdown page layout when I create a new page. Thanks in advance for any help!

    Luke.

    Reply

    • Hi Luke,
      if you download the visual studio solution and extract it you will find in the folder bin\debug folder a solution that you can install onto your environment.
      The article page DropDown.aspx needs to be stored in the same folder as the master page, because it’s a article page layout. You you also should define the content type as article page layout.
      What then happens is that you can create multiple pages from this page layout.
      All that is in the layouts folder in the visual studio solution should be in _layouts. I recommend you to deploy the solution and not copy the files manually.
      If i find time i can create out of this farm solution a sandbox solution.

      Kind regards
      Stefan

      Reply

  5. Just sharing an adjustment I made:

    In the current solution, all dropdown content is loaded when the user hits a page.
    That could mean the content of (example) 8+ dropdown pages is loaded, all at once.
    Even though this is an asynchronous process, it generates 8+ page loads for every page opened.
    And even if the user doesn’t open a dropdown menu item, that load takes place.

    I changed my code so the loadingData call is only made when the user hits a menu item.

    The downside is that the data is not readily available to be shown but needs to be loaded just in time.

    The upside is that loading the data normally only takes 60-80 ms, fast enough for a good enduser experience.
    And btw: with caching the load time can be even faster…

    var showFlyOut = function () { if ($(this).children(".mdd-itemcontent").html() != null) { $(this).children(".menu-item").addClass("hover"); $(this).children(".mdd-itemcontent").fadeIn("fast"); } else { loadingData($(this)); } }

    Reply

    • Thank you very much for sharing your improvements. I’ll check this out.

      Reply

  6. Hi Stefan,

    Quick question:
    If you manually add menu items for the megadropdown functionality, this navigation tab will show to be ‘selected’.
    Say I add News as a navigation tab and add links to News pages in that navigation dropdown, when the user hits one of those newspages the News navigation tab will not show as ‘selected’ cause it’s not a ‘subsite node’.
    Any thoughts on this?

    Reply

    • Well as far as i know it should (not verified yet). Are you sure that you have the correct page layout applied? Because otherwise the Div Container with the content cannot be found.
      Another thing is that you cannot do this cross domain because the browser will deny to embed the content.
      Have you check the console of the browser if there are any errors ?

      Reply

  7. Hi Stefan,

    This is Great!

    I wonder if this will work on Sharepoint 2013 Cloud / 365?

    SPbb

    Reply

    • Well it should work but i haven’t tried yet. I don’t see a technical limitation for this.

      Reply

  8. Stefan,
    Awesome and thanks so much for sharing.

    Just what i am looking to put into a SP2013 intranet. I followed your post and created a Menu page layout and modified the ‘Seattle’ masterpage. For some strange reason it runs perfectly on the System Master ( but ‘Site Settings’ page only ) , however not on Sytem Master pages or the actual site. Considering they are both set to use same masterpage i am a bit non-plussed. Any thoughts, pointers or comments from others who have used this with SP2013.

    Thanks in advance,
    Mike

    Reply

  9. Got it working on SP2013. The ‘settings’ page is an _layouts page and still uses the ‘.s4-tn’ CSS class but the other masterpages do not. Add you own wrapper div with your own class name and change the two .js & CSS files to reference it. All good.Works well. Problem between my keyboard and my floor, as usual.
    Mike

    Reply

    • Great to hear you managed it to work. Thank you for sharing the solution too.

      Reply

    • Can you give me the code for the wrapper ? I have it also on SP2013 and only the ‘settings’ page is working. The issue is that all s4-…. tag are missed in other than `settings`page. This effects also the CSS.

      Reply

      • The code is available to download on this blog post.

        /Stefan

        Reply

        • OK, but not the wrapper for SP2013 michael dockray has coded.
          Right ?

          Reply

          • Oh that you mean. Sorry but I don’t have his code. All you need to do is to change some id’s according to the new seattle master page.

            /Stefan

  10. I installed the feature using the wsp and deploying with powershell. My issue is that when I create a new page and select the dropdown naviagtion it doesn’t do anything and stays with the default body article page. Any ideas why this is happening?

    Reply

    • Can you please tell me a little bit more about your situation. Do you see the new article page? Do you get any error in the console of your browser (Press F12 in IE and heading for Console)
      Thank you.

      Reply

  11. Hi Stefan

    I’m having sort of the same issue as Michael in SP2013. Got it to work by creating a wrapper div for the menu. For some reason the Javascript stille doesn’t work on the publishing page. It works perfectly on the settings page.

    It looks like the script doesn’t “catch” the link and adds the content….

    Michael: Could you perhaps post your masterpage navigationcode that works?

    /Ulrich

    Reply

    • Hi Ulrich!
      The problem that David had, was that show pages wasn’t enabled for the top navigation. After he set this property it worked for him without any problem. I have some time tonight to try it on SharePoint 2013.
      I will provide you with an update after I tried.
      /Greetings
      Stefan

      Reply

  12. Hi Stefan

    I created a new page, assigned it as the deafult starting page and then it worked like a charm. Can’t explain why. 🙂

    Otherwise… Great work. Looking forward to see your 2013 solution…

    /Ulrich

    Reply

    • This might is because if you have in the navigation for example /subsite/ then SharePoint needs to redirect to go to /subsite/pages/navigationentry.aspx and this is something jQuery cannot handle. Anyway. I will try what I can do to improve it for SharePoint 2013. Thank you very much for your reply.

      /Greetings
      Stefan

      Reply

  13. Great work Stefan.
    MegaMenu will be part of the new portal we prepare for 10.000 users.
    Best regards

    Reply

    • Thanks for your comment!
      Awesome to hear that so many people will see that mega menu 😉

      Greetings
      Stefan

      Reply

  14. Can anyone provide more detailed instructions on how to get this working in SP2013 in the cloud?

    I am assuming I can’t just use the files you can download from above since css classes and master pages are different from 2010 to 2013, but I would really like to get this working.

    Anyone?
    Thank you!
    David

    Reply

    • Hi David,

      i can provide you with some detailed information how you can get this running in the next couple of days. Had to do another blog post first. Stay tuned.

      Stefan

      Reply

  15. Thank you so much for your efforts on this project! What a great solution.

    When implementing in a Office 365 SharePoint 2013 environment what I can’t figure out is if I have Publishing features enabled and create a new page and then review it’s code in SPD, I don’t see anything in the way of code that looks like what is in your instructions where I can wrap a webpart in a div.
    Help me Obie Wan, you’re my only hope. :- )

    Reply

  16. Hi Stefan,
    I have this working in 2013 in the cloud with the exception of publishing pages. Were you able to resolve the issue? It appears to be the same issue that Ulrich was having below.
    Any help would be appreciated.
    Thanks!

    Reply

    • I updated the blog post that should possibly resolve the issue but I haven’t tried in on office 2013 yet.

      Reply

  17. Calendar Events won’t show if you use Web Parts in the Mega Menu. So you can’t use List Views or CQWP’s, etc. You can use Field Controls instead to enter HTML, but you can’t insert Web Parts inside the Field controls.

    Reply

    • Hi Scott, thanks for your comment. I think you had the same issue as David. The new version is fixed.
      Please tell me if it works for you.
      /Stefan

      Reply

  18. Have you heard of anyone having an issue with the calendar webpart not showing events after applying mega menus? In fact the events show up in the mega menu. I could provide pictures if that would help…

    Reply

    • Hi David,
      thank you for your screenshot. I think your problem is solved now.
      Can you please check if it works for you=
      Kind regards
      Stefan

      Reply

  19. Hi, thanks for this. How can I modify this to work on SharePoint 2007?
    I tried but I’m not that good in javascript/jquery.

    Thanks for the help.

    Reply

    • Well basically this will work in SharePoint 2007 too. The problem is I haven’t touched a SharePoint Server 2007 since SharePoint 2010 came out.
      I also still don’t have access to a 2007 Server. Sorry that I won’t be much help in this case.

      Reply

  20. @Stefan, thanks for the quick answer. I decided to go another way and develop a new navigation control. Merry Christmas to you.

    Reply

    • Hi Vincent.
      I wish you all all the best for your control.
      Merry Christmas to you too.

      Reply

  21. Hi Stefan,

    This Mega-Menu solution is Great!

    I have been successful in deploying your solution to my SP development server and applying the appropriate changes to my custom master page. I have also created a couple of article pages and those show up on the menu.

    Where I am stuck though is due to my inexperience with CSS and HTML? Would you be able to post the code you used in your “News” and “Products” tabs?

    Thanks ahead,
    Peg

    Reply

  22. I got it!

    After re-viewing your demo today (and strong coffee) I saw that the web-part used in your products page was the “Summary Links”.

    I’m on my way…

    Thanks again for a super article!

    Reply

  23. Hi Stefan, thanks for this wonderful article and this is just what I was looking for. I have managed to make this work in 2013.

    Reply

  24. Thanks Stefan for sharing this article. I’m trying to implement this for SharePoint 2013 and have the following issues:
    a) MegaMenu pops as soon as the page loads.
    b) It works only once on Hover in IE and Chrome.

    Any help will be appreciated.

    Thanks.

    Reply

    • Sorry haven’t tried this under SharePoint 2013 yet but i’m looking forward to use it under 2013.

      Reply

  25. @AH
    As for the megamenu popping on pageload, you might want to try to set display: none; in the .mdd-itemcontent class. Had the same problem as you, but this worked for me.

    @Stefan
    Thank you for a very nice megamenu! Have a small issue I’m working with.
    I’m doing this in SP2013 on-prem but the appearance of the menu looks different depending on where the user is located. For example: I create a page > Navigation dropdown > Add Webpart > Summary Links > Add some dummy links > Check in + Publish > Hover the link: Looks nice. This is currently at the created News page.
    However, if I navigate to Home and hover the News link again, it looks different. Links are not placed in the same kind of neat order. If I go back to the News page and remove the webpart, the megamenu appears just like it did at Home again.
    In short: The appearance of the megamenudropdown changes according to the current location, the page and its webpart.
    Any thoughts about this? Might be a simple detail I’m forgetting, forgive me if so.

    Best regards
    Chris

    Reply

  26. I am very interested in this solution. My first thought is ALWAYS the end user and I am trying to avoid by-passing SP navigation all together. I am going to look at this solution but not sure I am piecing it all together.

    My biggest thought is I am going to use Twitter Bootstrap for SP, is mega menus really the way to go?

    Reply

    • Mega menu was a hype from a couple of years ago but with the upcoming responsive web design a whole new series of navigation design pattern was created. I think mega menus still have there place but I’m not sure if this will be in the case of a full responsive web design. You will find a great collection on Complex navigation design pattern.

      Reply

  27. Hi Stefan, I am new to sharepoint, I will like to know how to install this solution into a sharepoint 2013 foundation site. Thanks.

    Reply

    • Hi,

      this will only work together with the publishing features of SharePoint Server and is not supported in SharePoint Foundation.

      /Stefan

      Reply

  28. Hi Stefan,

    Did you get a chance to develop the solution for SharePoint 2013 yet. I really like the fact that site admins can manage / control the menu items easily via the Article page. Although I would also like to learn more about what Magnus was referring to in his post “using ajax to fetch data from an url to get the appropriate data for the mega menu in the current context”. Would also like to see if there is a way to have the menu populate based on security trimming (like the native menu).

    Thank you for putting this together and your thoughts.

    Sincerely,
    Tim

    Reply

    • Hi Tilm,

      thank you for asking. Yes I have currently a working solution but it’s not yet ready to ship.

      According to the security trimming: The security trimming depends on the web part you use. You can use table of content web part instead of summary link web part.

      /Stefan

      Reply

  29. Hi Stefan,
    Complete development novice, but looking for a enhance navigation experience for my SharePoint Online tenant as the OOB layout and formatting is not the best. Did you get to a point of a working SPO version and is it straight forward enought for a novice to follow and implement. I am trying to keep our implementaion free of masterpage changes, given the MS guidance around such in an SPO environment, grateful for any thoughts you might have on this.

    Thanks

    Paul

    Reply

    • Hi Paul,
      thank you for your feedback. I used this mega menu a couple of times in customer projects even on Office 365 now. What you need to adapt this is to change certain ID and class names to get this running. If you don’t like to change the master page you can simply inject all the required elements via jQuery / JavaScript into the master page.

      /Stefan

      Reply

  30. Hi Stefan, I have been having a bit of the play with the solution you detail in this post, its fantastic.

    I have deployed it on prem in SharePoint 2013 on my dev box and found I have one issue. I can create the pages and get them to display as dropdowns, but not every web part is displaying.

    Static content like a content editor web part or the summary links web part works fine, web parts like any list view web part or the content search web part do not appear to return any HTML in the Ajax call, just an empty web part zone.

    2 Questions, I assume this should be working with these types of web part and returning dynamic content, is this correct ?

    and if this is the case, any thoughts as to why this would not be working ? The function I am using to do the Ajax call is pretty much identical to the one you use in the sample code.

    Thanks

    Phil

    Reply

    • Sorry but it only works with static content web parts. When you send the ajax call to request the web page you request the source code of the page and all that is static embedded there. During the ajax request no client side code will be executed to render the list views, search web part and other dynamic content.

      For list view web part you can disable the client side rendering. The content should then be visible in the drop down.

      /Stefan

      Reply

      • Thanks Stefan, I suspected that would be the case. Interesting tip on the list view web part though, new for me thanks.

        Reply

  31. Hi Stefan, nice post. I am investigating a mega menu on SP2013 and this comes to my attention. The challenge to me is that the one of the menu is call My Links, which content is retrieved from My Site quick links, therefore, the content is different for each person. So far, all the solutions for SharePoint mega menu support static menu content, have not find any solution to support such dynamic content. Do you have any idea if this achievable?

    Reply

    • When you init the mega menu. You are free to do whatever you want to do. This means you can dynamically add a ‘My Link’ entry to the current navigation and add the dynamic content in a new container.

      This is the approach I would go. Hope this helps you a bit.

      /Stefan

      Reply

  32. Stefan, I am walking into a SharePoint 2013 environment created by others. The mega menu is functional (and huge) and it is in random order and that makes it extremely difficult to find any items. I have yet to figure out how to get this into alphabetical order. Have any advice? Thanks for all you do for the SharePoint community.

    Reply

    • Paul, hard to tell when you cannot see the mega menu or how it works. First, group all items somehow in a meaningful way and the order it alphabetical.
      There are even more things that should be considered.
      What are the most used items?
      What items are obsolete?
      Which item should be removed from the mega menu and represented on a own page?
      These are all questions that should help you to organise and create a more meaningful interface for the mega menu.

      Reply

Leave a Reply to AH Cancel reply

Required fields are marked *.


This site uses Akismet to reduce spam. Learn how your comment data is processed.