O365 – SharePoint Hosted App – Custom Global Navigation using Term Store

Hope you are all aware of the limitations of Managed Navigation in SharePoint. If not go through this article http://nikpatel.net/2014/06/09/limitations-of-managed-navigation-in-sharepoint-2013

As explained in the above article, each term set can be associated with only one site collection at given time. If you have 5 site collections, you must have 5 copies of same term set to use for 5 site collections navigation data.

To overcome this issue I have created a SharePoint Hosted app which can read the term store and dynamically build the navigation. This app can be embedded in to webpart zone or master page based on your requirement.

O365 Patterns and Practice code helped me a lot to build this app – (Path – PnP-master\PnP-master\Samples\Core.TaxonomyPicker\Core.TaxonomyPickerWeb\Scripts\taxonomypickercontrol.js)

Step 1 – Create Term Set with your desired menu items and a custom property to configure the redirect url as shown below :

termstore

Step 2 – Create a SharePoint Hosted App using Napa / Visual Studio

Step 3 – Configure Permission as per your requirement

Permission

Step 4 – Add the necessary script files and a DIV tag to load the dynamic html from App.js file as shown below

Default Aspx

Step 5 – Build the dynamic menu list and push the html inside the DIV from App.js as shown below:

Note: Replace the term store and termset Guid with your environment values.

‘use strict’;

var terms;
var sb = “”;

var tree = {
term: terms,
children: []
};

$(document).ready(function() {
fn_Build_Navigation();

});

function fn_Build_Navigation() {
var start = new Date().getTime();
var context = SP.ClientContext.get_current();
var taxSession = SP.Taxonomy.TaxonomySession.getTaxonomySession(context);
var termStores = taxSession.get_termStores();
//Name of the Term Store from which to get the Terms.
var termStore = termStores.getByName(“Taxonomy_kFyvauM0tqfeNGG7M0bRmw==“);
//GUID of Term Set from which to get the Terms.
var termSet = termStore.getTermSet(“fa6a6655-4db6-4568-aa41-588b9420aec9“);
terms = termSet.getAllTerms();
context.load(terms);

context.executeQueryAsync(function() {
var termEnumerator = terms.getEnumerator();

while (termEnumerator.moveNext()) {
var currentTerm = termEnumerator.get_current();

var currentTermPath = currentTerm.get_pathOfTerm().split(‘;’);
var children = tree.children;

// Loop through each part of the path
for (var i = 0; i < currentTermPath.length; i++) {
var foundNode = false;
for (var j = 0; j < children.length; j++) {
if (children[j].name === currentTermPath[i]) {
foundNode = true;
break;
}
}

// Select the node, otherwise create a new one
var term = foundNode ? children[j] : {
name: currentTermPath[i],
children: []
};

// If we’re a child element, add the term properties
if (i === currentTermPath.length – 1) {

var navurl = currentTerm.get_customProperties().redirectTo;
if (!navurl) {
navurl = “#”;
}

term.term = currentTerm;
term.title = currentTerm.get_name();
term.guid = currentTerm.get_id().toString();
term.url = navurl;
}

// If the node did exist, let’s look there next iteration
if (foundNode) {
children = term.children;
}
// If the segment of path does not exist, create it
else {
children.push(term);

// Reset the children pointer to add there next iteration
if (i !== currentTermPath.length – 1) {
children = term.children;
}
}
}
}

if (tree.children.length > 0) {
sb = “<ul id=’globalMenu’ class=’menu’>”;

for (var prarentindex = 0; prarentindex < tree.children.length; prarentindex++) {
if (tree.children[prarentindex].children.length > 0) {
buildTermSetTreeLevel(tree.children[prarentindex].children, tree.children[prarentindex].name, tree.children[prarentindex].url);

} else {
sb += “<li><a href='” + tree.children[prarentindex].url + “‘>” + tree.children[prarentindex].name + “</a></li>”;
}
}

sb += “</ul>”;

$(“#message”).html(sb);
}

var end = new Date().getTime();
var time = end – start;
console.log(‘Execution time: ‘ + time);
}, function(sender, args) {
console.log(args.get_message());
});
}

function buildTermSetTreeLevel(termList, name, url) {

sb += “<li>”;
sb += “<a href='” + url + “‘>” + name + “</a>”;
sb += “<ul>”;

for (var i = 0; i < termList.length; i++) {
var term = termList[i];

if (term.children.length > 0) {
buildTermSetTreeLevel(term.children, term.name, term.url);
} else {
sb += ” <li><a href='” + term.url + “‘>” + term.name + “</a></li>”;
}
}

sb += “</ul>”;
sb += “</li>”;
}

Hope you liked this post. If you have any questions on this topic, please let me know…

Advertisements

About Joseph Velliah
As a SharePoint Developer my professional interests tend to be technical and SharePoint focused. I run a blog at "SP RIDER" where you can expect to read HOW TOs and scenarios that I run into during my day to day job. I hope my posts will give back a little to the community that is helped me.

Comments are closed.

%d bloggers like this: