Search result for:
Press ESC to close Search Result or press here

n8design


Art, Design, Media, Web & SharePoint … by Stefan Bauer
7. November 2012

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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comments
  • Marc D Anderson commented at 7. November 2012 at 05:45

    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.

    • Stefan Bauer commented at 7. November 2012 at 20:51

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

      /greetings
      Stefan

  • Magnus Hansson commented at 7. November 2012 at 09:23

    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)

    • Stefan Bauer commented at 7. November 2012 at 14:35

      Yes i will be at the SPC. ;)

  • Christian Stahl commented at 7. November 2012 at 09:43

    Just looked at the video, really cool & great work! Can’t wait to try this out.

  • Ernst Wolthaus commented at 19. December 2012 at 07:39

    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?

    • Stefan Bauer commented at 19. December 2012 at 10:59

      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/

  • Ernst Wolthaus commented at 19. December 2012 at 11:17

    Thanks Stefan.
    I already implemented the “event.preventDefault” ;-)

    I also applied the Hoverintent plugin. Even nicer!
    http://cherne.net/brian/resources/jquery.hoverIntent.html

    • Stefan Bauer commented at 19. December 2012 at 12:11

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

  • Luke commented at 8. January 2013 at 21:57

    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.

    • Stefan Bauer commented at 9. January 2013 at 00:49

      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

  • Ernst Wolthaus commented at 9. January 2013 at 08:24

    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));
    }
    }

    • Stefan Bauer commented at 9. January 2013 at 08:32

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

  • Ernst Wolthaus commented at 28. January 2013 at 13:52

    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?

    • Stefan Bauer commented at 28. January 2013 at 14:07

      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 ?

  • SPbb commented at 28. March 2013 at 17:52

    Hi Stefan,

    This is Great!

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

    SPbb

    • Stefan Bauer commented at 29. March 2013 at 00:47

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

  • Michael Dockray commented at 15. May 2013 at 06:55

    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

  • michael dockray commented at 17. May 2013 at 08:48

    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

    • Stefan Bauer commented at 17. May 2013 at 08:48

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

  • David commented at 10. June 2013 at 11:34

    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?

    • Stefan Bauer commented at 10. June 2013 at 11:38

      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.

  • Ulrich commented at 13. June 2013 at 09:35

    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

    • Stefan Bauer commented at 13. June 2013 at 09:39

      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

  • Ulrich commented at 13. June 2013 at 10:28

    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

    • Stefan Bauer commented at 13. June 2013 at 10:29

      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

  • mkrous commented at 11. September 2013 at 17:46

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

    • Stefan Bauer commented at 11. September 2013 at 17:48

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

      Greetings
      Stefan

  • David McGuffin commented at 21. September 2013 at 02:21

    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

    • Stefan Bauer commented at 21. September 2013 at 16:10

      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

  • David McGuffin commented at 23. September 2013 at 15:41

    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. :- )

  • Lorena commented at 6. November 2013 at 01:24

    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!

    • Stefan Bauer commented at 19. December 2013 at 11:55

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

  • Scott McLeod commented at 14. November 2013 at 14:39

    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.

    • Stefan Bauer commented at 19. November 2013 at 00:32

      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

  • David commented at 18. November 2013 at 21:39

    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…

    • Stefan Bauer commented at 19. November 2013 at 00:34

      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

  • Vincent commented at 19. December 2013 at 15:17

    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.

    • Stefan Bauer commented at 20. December 2013 at 01:36

      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.

  • Vincent commented at 20. December 2013 at 09:33

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

    • Stefan Bauer commented at 20. December 2013 at 22:24

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

  • PegH. commented at 6. January 2014 at 03:17

    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

  • PegH. commented at 6. January 2014 at 18:28

    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!

    • Stefan Bauer commented at 6. January 2014 at 21:10

      Great that you could solve it and thanks for your comment.

  • KK commented at 5. February 2014 at 18:22

    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.

  • AH commented at 5. February 2014 at 18:51

    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.

    • Stefan Bauer commented at 6. February 2014 at 14:47

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

  • Prasenjit Paul commented at 15. April 2014 at 08:09

    Thanks for the article.It is of great help


%d bloggers like this: