1,804 articles and 14,581 comments as of Friday, February 11th, 2011

EndUserSharePoint has combined resources with NothingButSharePoint.com. You can now find End User (Mark Miller), Developer (Jeremy Thake) and IT Pro SharePoint (Joel Oleson) content all in one place!

This site is a historical archive and is no longer being updated. Please update your favorites, bookmarks and RSS feeds.

NothingButSharePoint.com
Thursday, April 22, 2010

SharePoint: Application Wide Quick Launch Control

Guest Author: Michael Greene
Hyper-TechDesign

I ran into a unique challenge on a recent project related to the use of the Quick Launch. I had a Web Application that was broken into about 10 Site Collections to facilitate access control, but had the potential to become an absolute bear to manage. The Quick Launch needed to be the same across all of the Site Collections, which resulted in having to physically touch the configuration of each Site Collection or Subsite every time a link needed to be added or changed. There had to be a better way, right?

Enter the SPServices jQuery library by Marc Anderson (@sympmarc). It should be pointed out that I’m working in WSS 3, but I don’t know of anything that would prevent this from working in MOSS (although the jQuery selectors may need to be changed).

Creating a Common Repository

To attack this issue, I first created a Site Collection in the Web Application called ‘Common’, which serves as a central repository of resources used throughout the Web Application. Here I store all of the graphics, scripts, libraries and other master control lists which will be utilized by all of the Site Collections within the Web Application. I’ve restricted permissions to just the three administrators, as we’ll store some maintenance documentation and other pieces of information here too as reference point for the entire Web Application. I also created a Document Library called ‘Scripts’ in this Common Site Collection to contain the core jQuery library, SPServices, the script file itself, and any additional scripts that may get added in the future.

Quick Launch Control List

Next I needed to create a list that will hold all of the Quick Launch links. To me, the easiest way to do this was to just create a Links list called “Quick Launch”. Once the list was created, I needed to break the inheritance of permissions for this list, and allow all users read access. While I normally try to avoid breaking inheritance (purely from a manageability standpoint), in this particular use I really don’t want to grant everyone access to everything on the site, so we’ll do it on each individual library or list that contains information needing access (including the Scripts library referenced above).

The Script

Now that the list has been created we can start to think about how to get the data out of it and into the Quick Launch itself. After carefully reviewing the DOM surrounding the Quick Launch I was able to determine the structure so we can and replicate it ourselves. Believe it or not, this rather simple script is only 20 lines long.

The SharePoint Quick Launch menu is contained within a table with an id of “zz2_QuickLaunchMenu”. It’s important to note that if there are no Quick Launch links defined in the Site Settings, SharePoint does not write this parent table, so our script must contain provisions to look for that element and create it if it’s not present. For my purposes, I wanted to make sure that only links added in our master list would appear in the Quick Launch menu, so I’ve added a line to clean out the contents of that table, erasing anything defined at the site level before adding the links in (line 9). Obviously you can comment out this line, which will allow you to define one off links at the Site Collection level and combine them with links defined in the master list.

I’ve based the script around the “zz2_QuickLaunchMenu” element in order to determine if Site Collection defined links are already there, and provisioned to create that element if it’s not there. There are other ways to do it, such as using the .ms-quicklaunch div element, though you’d then have to create your table after the “View All Site Content” link, and before the Recycle Bin link. Utilizing the same DOM as out of the box SharePoint eliminates that issue.

var i = 1; // Quick Launch buttons are numbered, so we need to keep track of this as we go.
$(document).ready(function() { // wait for the DOM to complete, then build our Quick Launch
$().SPServices({
operation: "GetListItems",
webURL: "http://server.domain.tld/common", // URL to our common repository
listName: "Quick Launch",
completefunc: function(xData, Status) {
if ($("#zz2_QuickLaunchMenu").length) { // Is there already a QuickLaunchMenu element present?
$("#zz2_QuickLaunchMenu").html('<tbody></tbody>'); // Clear out what the SP collection has populated
} else { // No Quick Launch, so we must write the containing table element(s)
$("#ctl00_PlaceHolderLeftNavBar_QuickLaunchNavigationManager div").append('<table id="zz2_QuickLaunchMenu" class="ms-navSubMenu1 zz2_QuickLaunchMnenu7 zz2_QuickLaunchMenu_2" cellspacing="0" cellpadding="0" border="0"><tbody></tbody></table>');
}
$(xData.responseXML).find("z\\:row").each(function() { // For each row of our web service return
var URLdata = $(this).attr("ows_URL").split(','); // Links lists store URL and title together, seperated by a comma, so we must split apart this string
$("#zz2_QuickLaunchMenu > tbody:last").append('<tr id="zz2_QuickLaunchMenun' + i + '" onkeyup="Menu_Key(event)" onmouseout="Menu_Unhover(this)" onmouseover="Menu_HoverRoot(this)"><td><table class="ms-navheader zz2_QuickLaunchMenu_4" width="100%" cellspacing="0" cellpadding="0" border="0"><tbody><tr><td style="width: 100%;"><a class="zz2_QuickLaunchMenu_1 ms-navheader zz2_QuickLaunchMenu_3" style="border-style: none; font-size: 1em;" href="' + URLdata[0] + '">' + URLdata[1] + '</a></td></tr></tbody></table></td></tr>'); // add a new row after the <tbody> tag containing the link
i++; // Add 1 to i to give the next link the next ID
});
}
});
});

Note that I’ve replicated all of the same CSS classes which are present in the default Quick Launch structure.  This is important because we want our custom Quick Launch to render with the same branding (or “look and feel”) as an uncustomized Quick Launch.  This way, if we change the CSS over time, our customized Quick Launch will pick up the changes the same way an uncustomized one would.

As this script will be used by every Site Collection in the Web Application, we’re going to want to go ahead and make it as a separate file and store it in our common repository. This way if we decide in six months that it needs to be edited, we have a single point to do that.

Deployment

Now that we’ve created the script, all we need to do is deploy it. Open up the master page for the Site Collections you want to manage, and reference the necessary libraries and the Quick Launch script. I generally make these calls directly after the opening <body> tag.

<BODY scroll="yes" onload="javascript:if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();">
<script type="text/javascript" src="/common/Scripts/jquery.js"></script>
<script type="text/javascript" src="/common/Scripts/jquery.SPServices.js"></script>
<script type="text/javascript" src="/common/Scripts/quicklaunch.js"></script>
<form runat="server" onsubmit="return _spFormOnSubmitWrapper();">

Conclusion

As I solved this problem I started to think about other possible uses for this concept. The idea of a central repository for graphics and scripts is nothing new, but this was the first time that I have used lists in one Site Collection to feed content throughout the Web Application. The value-add of this level of control is a huge saver of labor when it comes to maintaining large managed applications.

Guest Author: Michael Greene
Hyper-TechDesign

Michael Greene is the founder and president of Hyper-TechDesign, based in Binghamton, NY. With over a decade of experience in the internet development arena, Michael specializes in helping customers adopt and integrate technology to increase efficiency and foster improved collaboration, customer interaction and communication. He is also a frequent participant in SharePoint discussions on Twitter, and operates his personal blog, mike-greene.com.

 

Please Join the Discussion

7 Responses to “SharePoint: Application Wide Quick Launch Control”
  1. spevilgenius says:

    Pretty wicked Micael (thats a technical term!) This just goes to show there are many ways to accomplish a task using Marc’s library. I am using it for a lot of things!

  2. Peter Allen says:

    Michael,

    Great solution. I noticed that list of links was not in alphabetical order when displayed in the Quicklaunch. I then played with the default view of the list in the list library and saw that by making it a descending view it would show up as an ascending view on the Quicklaunch, strange. Is there any other way to order these?

    Also, with regards to your site collections. I setup my client very similar to what you have done, but I have a web app for SP Configuration and then have two site collections. First site collection has all the SP Configuration documentation, this is restricted to those who need access. Second site collection is called resources and is where we put all the scripts, images, and other global list needed for all other site collections and this has read access by all.

    Thank you for sharing. This is a great solution for addressing global navigation across web apps and site collections.

  3. Peter,

    Your other option, vice the view technique is to pass a CAML Query with the GetListItems web service. You can use that to set your where, and, or, order by, etc. query parameters and get the output you want.

    Mike

  4. Peter Allen says:

    Thank to Michael for this great solution. I have been playing with it and have created a Quick Launch version that will group and you can choose to have the header be a link or not.

    Also, I got to thinking about Top Navigation drop down and adapted his code to work on a drop down. The top navigation can be added at the beginning or end of the top nav bar.

    Here is an example of what I have done so far: http://www.bitsofsharepoint.com/ExamplePoint/Navigation/default.aspx

    I will be writing two articles on each one.

    THANK YOU Michael for creating this solution!!!

    THANK YOU Marc Anderson for creating the SPServices jQuery Library.!!!!

    Great stuff.

  5. Frank says:

    I know it has been awhile but can you provide how to ’screen shots’? I just got the ‘go’ to change our Intranet sites. We are using MOSS.
    Thanks,
    Frank

  6. maysam biglar says:

    hi, dear sir
    how can i change quick lunch alignment? i want to change its direction right-to-left.
    thank you for your help, beforehand.
    maysam.

Trackbacks

Check out what others are saying about this post...
  1. [...] 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 [...]




Notify me of comments to this article:


Speak and you will be heard.

We check comments hourly.
If you want a pic to show with your comment, go get a gravatar!