B i t s O f S h a r e P o i n t C o n s u l t i n g L L C > B l o g P o i n t > Posts > SharePoint - A Global Navigation Solution across Site Collections
SharePoint - A Global Navigation Solution across Site Collections

Ever want to have an easier way to have a global navigation that spans across site collections?  SharePoint provides a solution for global navigation within a site collection and it works well.  But when you architect SharePoint to have multiple web apps and site collections you do not have any easy solution to create a global navigation system to span those repositories.  You would have to recreate your global navigation on each site collection.  And any changes to the global navigation would mean that you would have to go to each site collection to make the change…ouch!!!  There has got to be a better solution.

Thanks to Marc Anderson and Michael Greene who have created solutions that inspired me to explore solving this problem.  Marc Anderson created SPServices, which is a jQuery library for SharePoint Web Services.  I am beginning to understand the power of his solution.  Then Michael Greene created a solution, Application Wide Quick Launch Control, where you can change or append the Quick Launch on SharePoint sites.  Michael’s solution used Marc’s SPServices and jQuery.

Based on what these two have done, I then looked into how we could apply this to the Top Navigation found in SharePoint.

 

My goal was to do the following:

  1. Be able to add a tab at the beginning or end of the Top Navigation bar.
  2. Create a pull down to maximize space.
    • Ever see a top nav bar with too many tabs, ouch.
  3. Pull down items are pulled from a standard SP Links list.
    • Imagine being able to add an item to a list and it is then apart of the top navigation across site collections, yes!
    • WSS does not give us the ability to have a pull down, lets change that.
  4. Ability to order and group pull down items.
    • Organization is critical to ease of use.
  5. Grouping Headers can be links or not.
  6. Navigation tab and pull down changes with site theme.
  7. Tabs can be links or not.

What is the end product going to look like, well, something like this.  Where we have added a tab called “Services” with a pull down that is grouped.  This is a WSS site, where this is not possible out of the box.

 

And we are pulling this from a list.  Take a look at the TopNav links list below.  You can see the grouping and ordering is working as well.

 

Now lets walk through what we have to do to get the above results.

Components needed:

  1. SharePoint Resource Site
  2. SPServices by Marc Anderson
  3. jQuery
  4. SharePoint Designer to edit Master Pages
  5. SharePoint Links List
  6. Solution Code

1) SharePoint Resource Site

I recommend that if you do not already have a site collection devoted to scripts and lists that will be accessible by all, that you create one.  This site collection will allow you to have document library where you can house your scripts like jQuery and SPServices.  It will also allow you to create lists as needed for example the one we will create to manage the pull down items in our tab.

So there should be a site collection where we house the below files and list and that has permissions set to all authenticated members as read only. For purposes of this article I will call this site collection Resources. I wrote an article along these lines and here it is: http://www.bitsofsharepoint.com/BlogPoint/Lists/Posts/Post.aspx?ID=29

2) SPServices by Marc Anderson

We need to download the SPServices file that Marc Anderson has put together.  You can find it here: http://spservices.codeplex.com/ This file will be used by the script for this solution, so this will need to be added to the document library where you keep scripts.  In my case it would go into the document library in my Resources site collection.

Recommendation is to change the name of the file name so that it does not have a version number and should look like this, “jquery.SPServices-latest.min.js”.  This will allow you to update in the future to Marc’s latest version without having to go back to each master page and change to the new version name.

3) jQuery

There are two ways to work with a jQuery file.  You have a choice of downloading the latest version and putting it in scripts document library or you can point to Google's version which will always be the latest version.  This is a choice that you will make.   You can download jQuery from here: http://jquery.com/

I would then add this script to me document library in my Resources site collection.

4) SharePoint Designer to edit Master Pages

You will need to have access to SharePoint Designer and be able to edit the Master Pages on the sites you want the global navigation tab to show up on.  When you edit a master page you will want to add the following code between the <header></header> tags as diagramed below. 

 

Here is the code you will need to add to each master page.  Make sure that the URL’s point to where you have the files housed.  They do need to be absolute URL’s, as you will be adding this code across site collections, web apps and even servers.

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="http://yoursite/SiteCollection/LibraryName/jquery.SPServices-latest.min.js"></script>
<script type="text/javascript" src="http://yoursite/SiteCollection/LibraryName/topnavigation.js"></script>

For example if I put “jquery-latest.js”, “jquery.SPServices-latest.min.js”, and “topnavigation.js” in my Resoures site collection in the document library called ScriptsLibrary, then it would look like this:

<script type="text/javascript" src="http://www.bitsofsharepoint.com/Resources/ScriptsLibrary/jquery-latest.js"></script>
<script type="text/javascript" src="http://www.bitsofsharepoint.com/Resources/ScriptsLibrary/jquery.SPServices-latest.min.js"></script>
<script type="text/javascript" src="http://www.bitsofsharepoint.com/Resources/ScriptsLibrary/topnavigation.js"></script>

5) SharePoint Links List

Now to create the ease of updating and managing the content in the pull down for the tab, we will need to have a list where the solution can pull the links from.  But we also need to create some organization and groupings. So will will create a links list and add some additional columns.

In my Resources site collection I will create a list called TopNav, you are free to name it what you like.  This TopNav list will be a Links list.  Once created we need to add a couple of other columns:

  • Group – This column will be used to group the links together.  So all “Help” links will be together and all “Features” links will be together. 
    • This is a text field or it can be a choice field if you know all the groups.  
  • LinkType – This column will be used to identify what type of link it is.
    • This is a Choice column. 
    • We have three choice types and each will cause the pull down to display the link in different way:
      • Link – This will display the item as a link within the group.
      • Header – This will display the item as a header without a link.
      • Header Link – This will display the item as a header with a link.
        • (Header and Header Link look them same, but act differently)

Next you will want to change the default All Links view to the following:

  • Sort – Change the following:
    • All users to order items in this view, set to “No”.
    • Sort by “LinkType” in “ascending order”.
    • And Sort by “URL” in “ascending order”.
  • Group By – Change the following:
    • Group by to “Group” in “ascending order”.
    • Show grouping as “Expanded”.

This new view will be the way the items show in the pull down for the global navigation.  So you can play with the view here to sort and group it as you wish.

Here is an example of what it should look like once you have several links listed.

 

Almost there……yeah.

6) Solution Code

Ok, now for the code that will make this all work together.  There is a file called topnavigation.js that we will need to be created and edited to make it work in your environment. 

In my case it would go into the document library in my Resources site collection.

To make this script work you will need to provide several pieces of data which are listed out below.

  1. [tabSide] - Specify either 'append' or 'prepend'. This will indicated if the new tab will go before or after the default tabs.
    • Tab front Example: 'prepend'
    • Tab End Example: 'append'
  2. [titleTabName] - Specify a name for the tab, this will be displayed in the tab.
    • Tab Name Example: 'Intranet'
  3. [urlTab] - Specify a link only if you want the tab to be clickable, otherwise leave blank with two quotes, ''.
  4. [listName] - Specify the name of the list for the pull down.
    • List Name Example: 'Links'
  5. [listSiteUrl] - Specify the url of the site where the list is located. URL needs to be of the site location NOT of the list location.

All above variables will then be constructed as follows, make sure that each field has a ' at the beginning and end of each.

You can have multiple extendTabs like so:

    extendedTabs('append','Projects','','Projects','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/');
    extendedTabs('append','Team Sites II','http://www.google.com','Team Sites','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/');
    extendedTabs('prepend','Intranet II','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/default.aspx','Links','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/');

    There will be three tabs added, with one added the to the front and two added to the back.

    Placement of your extendedTabs will dictate the order the tabs are displayed.

    Here is the code to add to the topnavigation.js file or you can download the topnavigation.js file from here: http://www.bitsofsharepoint.com/ExamplePoint/CodeExamples/topnavigation.js

    $(document).ready(function(){
    /*
    Extended Tabs by Peter Allen
    Version 1.0 5/3/2010
    Purpose: Add a tabs to the beginning (prepend) or end (append) of the default SharePoint Top Navigation tabs.
    Script Setup: To make this script work you will need to provide several pieces of data which are listed out below.

    [tabSide] - Specify either 'append' or 'prepend'. This will indicated if the new tab will go before or after the default tabs.
                    Tab front Example: 'prepend'
                    Tab End Example: 'append'
    [titleTabName] - Specify a name for the tab, this be displayed in the tab.
                    Tab Name Example: 'Intranet'
    [urlTab] - Specify a link only if you want the tab to be clickable, otherwise leave blank with with two quotes, ''.
                    Link Example: 'http://www.google.com'
                    No Link Example: ''
    [listName] - Specify the name of the list for the pull down.
                    List Name Example: 'Links'
    [listSiteUrl] - Specify the url of the site where the list is located. URL needs to be of the site location NOT of the list location.
                    Incorrect Example: 'http://www.intranet.com/SiteName/List/ListName/'
                    Correct Example: 'http://www.intranet.com/SiteName/'

    All above variables will then be constructed as follows, make sure that each field has a ' at the begining and end of each.

    Construct:
        extendedTabs('[tabSide]','[titleTabName]','[urlTab]','[listName]','[listSiteURL]')
    Example:
        extendedTabs('append','Projects','http://www.sites.com/Projects/','Projects','http://www.site.com/Resources/');
    This example adds a tab called Projects at the end, tab links to the Project site, the list for the pull down is called Projects and the list resides in the Resources site.

    You can have multiple extendTabs like so:

        extendedTabs('append','Projects','','Projects','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/');
        extendedTabs('append','Team Sites II','http://www.google.com','Team Sites','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/');
        extendedTabs('prepend','Intranet II','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/default.aspx','Links','http://www.bitsofsharepoint.com/ConsultingPoint/ClientPoint/snc/');

    Placement of your extendedTabs will dictate the order the tabs are displayed.

    */

    //    Place your extendedTabs below:

        extendedTabs('append','Projects','http://www.site.com/site/default.aspx','Projects','http://www.site.com/site/');
       

        var i = 1;
        function extendedTabs(tabSide,titleTabName,urlTab,listName,listSiteURL) {

            var titleTabID = 'zz1_TopNavigationMenun' + titleTabName.replace(/[-' ']/g,'');
            var showTabPD = titleTabID + 'Show';
            var showTabAppend = titleTabID + 'Append';

            if (urlTab != '') {
                var urlTabShow = 'href=' + urlTab;
            } else {
                var urlTabShow = '';
            }

                var tableRow = '<td id="' + titleTabID + '" onkeyup="Menu_Key(event)" onmouseout="Menu_Unhover(this)" onmouseover="Menu_HoverRoot(this)"><table  width="100%" cellspacing="0" cellpadding="0" border="0" class="ms-topnav zz1_TopNavigationMenu_4"><tbody><tr id="mouse"><td style="white-space: nowrap;"><a ' + urlTabShow + ' style="border-style: none; font-size: 1em;" class="zz1_TopNavigationMenu_1 ms-topnav zz1_TopNavigationMenu_3">'    + titleTabName + '</a><td valign="top" style="width:0pt;" ><img style="border-style:none; vertical-align:top;" alt="" src="/_layouts/images/menudark.gif"></td></tr></tbody></table><div style="position:absolute;height: 0px;z-index:1;"><div id="' + showTabPD + '" class="zz1_TopNavigationMenu_8" style="display:none;position:relative;top:0px; clip: rect(auto, auto, auto, auto);z-index:1;"><table cellspacing="0" cellpadding="0" border="0" style="top: 0px;" id="' + showTabAppend + '"></table></div></div></td>';
            if (tabSide == 'prepend') {
                $('table#zz1_TopNavigationMenu').children().children().prepend(tableRow);
            } else {
                $('table#zz1_TopNavigationMenu').children().children().append(tableRow);

            }

            $().SPServices({

                operation: "GetListItems",

                webURL: listSiteURL,

                listName: listName,

                completefunc: function (xData, Status) {

                    $(xData.responseXML).find("[nodeName='z:row']").each(function() {

                        var URLdataTN1 = $(this).attr("ows_URL").split(',');

                        var linksTN1 = $(this).attr("ows_LinkType");

                        if (linksTN1 == 'Header') {

                            $('#' + showTabAppend).append('<tr id="zz1_TopNavigationMenun' + i + '" onkeyup="Menu_Key(event)" onmouseout="Menu_Unhover(this)" onmouseover="Menu_HoverDynamic(this)"><td><table cellspacing="0" cellpadding="0" border="0" width="100%" class="ms-topNavFlyOuts zz1_TopNavigationMenu_7 ms-topNavFlyOutsHover"><tbody><tr><td style="white-space: nowrap; width: 100%;"><a style="border-style: none; font-size: 1em;" class="zz1_TopNavigationMenu_1 ms-topNavFlyOuts zz1_TopNavigationMenu_6 ms-topNavFlyOutsHover"><strong>' + URLdataTN1[1] + '</strong></a></td></tr></tbody></table></td></tr>');
                            i++;

                        } else if (linksTN1 == 'Header Link') {

                            $('#' + showTabAppend).append('<tr id="zz1_TopNavigationMenun' + i + '" onkeyup="Menu_Key(event)" onmouseout="Menu_Unhover(this)" onmouseover="Menu_HoverDynamic(this)"><td><table cellspacing="0" cellpadding="0" border="0" width="100%" class="ms-topNavFlyOuts zz1_TopNavigationMenu_7 ms-topNavFlyOutsHover"><tbody><tr><td style="white-space: nowrap; width: 100%;"><a style="border-style: none; font-size: 1em;" href="' + URLdataTN1[0] + '" class="zz1_TopNavigationMenu_1 ms-topNavFlyOuts zz1_TopNavigationMenu_6 ms-topNavFlyOutsHover"><strong>' + URLdataTN1[1] + '</strong></a></td></tr></tbody></table></td></tr>');

                            i++;

                        } else {

                            $('#' + showTabAppend).append('<tr id="zz1_TopNavigationMenun' + i + '" onkeyup="Menu_Key(event)" onmouseout="Menu_Unhover(this)" onmouseover="Menu_HoverDynamic(this)"><td><table cellspacing="0" cellpadding="0" border="0" width="100%" class="ms-topNavFlyOuts zz1_TopNavigationMenu_7"><tbody><tr><td style="white-space: nowrap; width: 100%;"><a style="border-style: none; font-size: 1em;" href="' + URLdataTN1[0] + '" class="zz1_TopNavigationMenu_1 ms-topNavFlyOuts zz1_TopNavigationMenu_6">' + URLdataTN1[1] + '</a></td></tr></tbody></table></td></tr>');
                            i++;

                        }

                    });

                }

            });

            $('#' + titleTabID).mouseover(function(){

                $('#' + showTabPD).show();

            });
            $('#' + titleTabID).mouseleave(function(){

                $('#' + showTabPD).hide();

            });

        }

    });

    OK, now lets pull this all together.

    1. Document Library where the following is housed:
      • jquery-latest.js
      • jquery.SPServices-latest.min.js
      • topnavigation.js”
    2. A links list created called TopNav
      1. Added columns:
        1. Group
        2. LinkType
      2. Changed All Links View
    3. Modified topnavigation.js file as outlined.
      1. Add a extendedTab call.
    4. Edited masters pages with SharePoint Designer to add the three lines of code.

    You should now be seeing something like this.

     

     

    Here is a working example: http://www.bitsofsharepoint.com/ExamplePoint/Navigation/default.aspx

    Hope this helps.

    Comments

    Or you could do something like this (works in WSS too)

    Check out this solution:

    http://www.binarywave.com/Lists/Tips%20and%20Tricks/DispForm.aspx?ID=1

    We implemented it at our company and haven't had many issues.  There are some navigation problems with it sometimes, but that's b/c I haven't modified those pages with this tweak.  It'll even allow for multiple levels of drop-downs!
    at 5/3/2010 9:19 PM

    Re: SharePoint - A Global Navigation Solution across Site Collections

    This solution only provides tabs and fly-outs based on the site collection.  The issue that I am solving is having the same Global Navigation show up across site collections and servers.
    Peter Allen at 5/3/2010 9:52 PM

    Nice Work, Peter

    I love seeing great uses of SPServices like this!

    M.
    (as in Marc D Anderson, author of SPServices)
    at 5/3/2010 10:22 PM

    Re: SharePoint - A Global Navigation Solution across Site Collections

    Marc,

    Thank you for creating SPServices.  Makes like a whole lot easier.  Looking forward to playing around with it more.
    Peter Allen at 5/3/2010 11:26 PM

    SP 2010

    Looks like a great solution to a painful problem!  Nice job.

    Is this supported in SP 2010?  I have tried deploying it in our dev environment and it's not working.  Double checked all the configurations/modifications.  No error messages, just no additional tabs.  Advice or help most welcome.  Thanks! 
    at 5/13/2010 8:03 PM

    Re: SP 2010

    This solution will not work for SP2010.  They have redesigned the html they use and have gone from tables to div's, which is a better format.  I should be able to create a solution that will work with SP2010, but will not be able to get to if for some weeks.
    Peter Allen at 5/13/2010 9:02 PM

    Thanks! 

    Thanks so much for the quick reply to my question.  I'll keep checking back for the new version.  I think this will really solve one of the main issues for us in deploying a new intranet on SharePoint. 
    at 5/14/2010 12:26 PM

    Clickable instead of Hover Menus

    Hi,

    Have you found a way to make the top level menu items "clickable" to expand the sub-menu instead of the default "hover"?

    Thanks
    at 8/13/2010 3:05 PM

    Re: SharePoint - A Global Navigation Solution across Site Collections

    Yes, you can change the code in topnavigation.js to make this happen.  Make sure the your Tabs are not links to make this work.

    Change the code from this (delete this code):

    $('#' + titleTabID).mouseover(function(){
    $('#' + showTabPD).show();
    });
    $('#' + titleTabID).mouseleave(function(){
    $('#' + showTabPD).hide();
    });

    To this (replace with):

    $('#' + titleTabID).click(function(){
    $('#' + showTabPD).toggle();
    });

    That should do the trick.
    Peter Allen at 8/13/2010 3:47 PM

    Thank you ... but have a question

    I am getting this to work perfectly on FF but am struggling with IE.  The navigation simply does not show up!  Do you know if there is a setting I have to turn on to get this to work in IE.  I would appreciate any help.

    Thank you!
    at 10/23/2010 10:26 AM

    Re: SharePoint - A Global Navigation Solution across Site Collections

    This should work in all browsers.   I have this working on my site and have tested it on all browsers.
    Peter Allen at 11/7/2010 11:07 AM

    Do we have a version that support highlighting text with a different color on mouseover?

    Do we have a version that support highlighting text with a different color on mouseover?  Just wondering.

    Also, it seems that it does not like commas.  Is this a bug? 

    Hey, thanks man.
    at 11/13/2010 1:51 PM

    Re: SharePoint - A Global Navigation Solution across Site Collections

    Regarding mouseover highlight, I used the standard SharePoint css classes so you can override them if you want.  Also if you change your theme the pulldowns will follow as well.

    As for the comma, that is a bug that I will put in the list of fixes to do.
    Peter Allen at 11/15/2010 10:23 AM

    Firefox shows dropdowns on load

    We implemented this and are using it in production but firefox users see all the dropdowns when the page loads.  Do you know why this would happen and any ideas how to fix it?
    thanks.
    at 12/3/2010 5:07 PM

    Fixed that bug I just posted about firefox showing the nav on page load

    put this at the end
    $('#' + showTabPD).hide();

    after: $('#' + titleTabID).mouseleave(function(){
      $('#' + showTabPD).hide();
    });




    at 12/3/2010 5:31 PM

    Add Comment

    Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.

    Title


    Body *


    Addition: 2 + 1 = *


    Please complete this equation.

    Email


    This is optional.
    Attachments

     T o p i c P o i n t

     E x a m p l e P o i n t