23 August 2011

SharePoint: Automatic table of contents for a page's sections

If you have really long pages in SharePoint with lots of sections, you can use the nifty jQuery plugin from Rochester Oliveira to automate the creation of the table of contents (TOC). Note that this is different from the table of contents web part built into SharePoint; that tool only handles pages and sites, not content within pages.
  1. Ensure you've uploaded jQuery to your SharePoint site (or site collection); usually, these files will go into the Site Assets area so they're accessible to all sites. For example, http://mydomain.org/SiteAssets/js/jquery/jquery-1.6.2.min.js.

  2. Also place the jquery.stoc.js file necessary for this task in a similar location.

  3. Reference these two JS files from your master page, page layout, or content editor web part.

  4. Add some JavaScript to trigger the TOC creation (see code below). You'll also need an empty DIV tag that will have the TOC injected into it.

  5. Add the necessary CSS to style the TOC and the UL tags. Rochester Oliveira's plugin page has some great examples to get you started.

One other change is necessary for it to work correctly: For some reason, on SharePoint 2010, it was appending #undefined to all the table of contents items. So I modified the JS in the jquery.stoc.js to this:
if (id == "" || typeof id === "undefined") { //if it doesn't have only, of course

id = "h" + tagNumber + "_" + i;
cacheHN.attr('id', id);
}
Now if id is undefined, it will generate one. So you're ready to test. If you wish to get fancier, you can add a True/False dropdown to the page layout for editors to choose whether a page will have a TOC (for instructions on conditionally displaying the dropdown, please see this post). This code can generate the necessary JavaScript based on the page layout's custom content column EnableTOC value:
<%= (Microsoft.SharePoint.SPContext.Current.Item["EnableTOC"] == null ||

Microsoft.SharePoint.SPContext.Current.Item["EnableTOC"].ToString() == "False")? "" :
" "
%>
In the above code, if EnableTOC is set to True, we trigger the TOC plugin on the element with ID toc; the plugin will search the element main-content for tags of type H2 and H3 ("start: 2"), and generate the TOC based on that structure using UL tags. Also, the toc DIV tag is hidden by default; the code above changes its display property to block.

If you always want the TOC to be generated, take it out of the server-side code and make it entirely client-side. In addition, because of a bug in SharePoint 2010, named anchors might not work correctly; in other words, you might click an item in the TOC and not have the page go to that part of the document. In that case, you can add this code as well, courtesy of fcorbeil on the Microsoft MSDN forum:
<script type="text/javascript">

setTimeout(Reload,2000);
function Reload() {
window.location.hash=self.document.location.hash.substring(1);
}
</script>

1 comment:

Anonymous said...

this looks great! i'm going to give it a try