Taxonomy navigation components for SharePoint Online using Office UI Fabric and JSOM

 Image 1

The purpose of this article is to explain in details the mechanisms for achieving a taxonomy navigation menu in SharePoint Online using Office UI Fabric and the JavaScript Object Model.

Solution overview

Source code

This example is now part of the repository OfficeDev Pattern & Practices available on GitHub:

https://github.com/OfficeDev/PnP/tree/master/Components/Core.TaxonomyNavigationComponents

Prerequisites

Before starting, you will need to install some prerequisites:

Deployment and use

Simply follow the procedure on GitHub ? in theREADME.mdfile.

Final result

Once the solution is deployed in your site collection, here’s what you should see:

Image 2

  • A responsive navigation main menu wired to a taxonomy term set and using the Office UI Fabric CSS classes for rendering.
  • A contextual menu and breadcrumb menu to insert directly in your pages.

Key points of this solution

Here is an overview of the solution. For more details, I tried as much as possible to comment directly in the source code:

  • This is a generic and reusable solution that you can use with your own taxonomy term set.
  • All CSS and menu behaviors come from the Office UI Fabric components. The navigation main menu is responsive by default.
  • All navigation components are added via the Knockout JS ‘component’ binding mechanism
  • All script dependencies are managed via Require JS, avoiding you to use the SP.SOD nightmare system.
  • The deployment sequence is done via the PnP cmdlets and SharePoint CSOM
  • The JavaScript code relies heavily on the use of “deferred” objects of jQuery. This will keep some “flatness” in asynchronous calls and avoid nested calls making the code much more readable. This technique is especially useful as long as you play with the CSOM of SharePoint (executeQueryAsync()).
  • We use the default “Oslo” master page from a publishing site with JavaScript injection to insert the main menu in all pages.
  • The navigation menus support multiple languages.
  • The default search box is integrated to the main menu navigation bar only by jQuery manipulations.
  • The friendly URLs and simple links are supported as well as physical URLs (aspx).
  • The source term set for the menu don’t have to be necessarily the term set used for the web navigation (for example in the case you only want simple links in your menu). However, to benefit of the friendly URLs, you can use directly the navigation term set configured for the navigation (like this example) OR a term set that reuses terms from it to get friendly URLs work.
  • The browser local storage is used in this example to show how to cache the main menu navigation nodes. You can reset the cache just by adding a custom property directly on the term set (see instructions on GitHub).
  • Component synchronization (contextual menu and breadcrumb) is done via the JavaScript Pub/Sub pattern. We use the Amplify JS library to manage this behavior.
  • You may have noticed that the SharePoint default navigation system can have some limitations. Among them, the impossibility of separating data sources by navigation menus, SharePoint limiting you to the global and current navigation (so no footer, header, etc.). With this approach, it is now possible to create as many navigation menus as desired on a page.
  • And finally, it’s an open source solution, so feel free to use it and improve it!

Styles and component behavior management

Why Office UI Fabric?

Office UI Fabric is a toolbox of reusable components and graphic styles for Office and Office 365. Its use allows your applications to adopt the same standards and components as the original platform, without having to manage styles and behaviors. If like me, CSS is clearly not your strength and you want to seamlessly integrate your applications very quickly with the rest of the platform, Office UI Fabric is made for you! You just have to use the bricks that suit you.

The official website is available here: http://dev.office.com/fabric.

Note that the project is primarily maintained by Microsoft designers and by the community. The GitHub project is available at: https://github.com/OfficeDev/Office-UI-Fabric.

In this example, we use the main navigation menu available in the list of components of Office UI Fabric:

Image 3

The advantage of these components is that they are, for the most part, “responsive” by default. It means that you do not have to integrate third-party frameworks (such as “Bootstrap”) to manage the mobile display. Reduced to a SharePoint Online context, it means that you do not have to change the master page.

Also note that there is a grid system available in the tool (like Bootstrap).

Component’s dynamic inclusion

At the time when “server side” SharePoint development was still in fashion, there was a handy technique for modularizing the inclusion of components within page layouts, application pages and SharePoint master pages (typically navigation menus, etc.): the”delegate controls”. With SharePoint Online, this technique is no longer possible, even by modifying the master page. We must now use a technique called ” JavaScript injection”. However, if you look at this technique on the internet, you will notice that the HTML structure is often added directly in the JavaScript code or even in the code behind of an .aspx page through a provider hosted Add-in. I think, this is neither “clean” nor modular in my opinion.

To address this problem, I use the “component” binding technique of the Knockout JS library. This mechanism allows to inject dynamically the HTML structure of a component directly from a separate file.

Image 4

For example, to insert the navigation menu on a pages, you just have to include the following line, and then to callko.applyBindings()only on this item to get the HTML structure of the component automatically inserted in the page. This technique provides similar behavior to “delegate controls ” and greatly enhances the code readability.

Image 5

Managing dependencies between JavaScript files

Pause
Personally, every time I have to work with SharePoint using JavaScript, the script loading order quickly becomes a real headache. Indeed, in general, when you use the SharePoint JSOM (JavaScript Object Model) with taxonomy, user profiles or other, it is necessary to respect a specific script loading order to get it work correctly (the most often, a dependency on sp.js).

Quite honestly, I’ve never been a big fan of the “Script On Demand” mechanism (SOD) offered by SharePoint by default, finding its syntax too “heavy”. In a context where updating the master page is no longer possible, which is becoming the standard with SharePoint Online (otherwise, it is possible to get out via the<SharePoint: ScriptLink />), it is not uncommon to have to do this kind of thing (taken from the example of PnP navigation menu): several nested calls to ensure the loading sequence.

Image 6

It is obvious that this kind of code, although perfectly valid, quickly becomes difficult to read for more complex needs. To solve this problem, so I use the library Require JS, which allows precisely to create modular JavaScript applications and manage dependencies between them (a library or external file to your application can be seen as a module).

Image 7

From the SOD syntax seen previously, we get the following equivalent with Require JS:

Image 8

With this configuration, we ensure to have all the dependencies loaded when executing code in the taxonomy module:

Image 9

Another benefit is that Require JS modules are resolved relatively from a main script. Simply include only one script in the page so that all dependencies will be automatically resolved relatively to the main script according to the folder hierarchy in the style library of the SharePoint site:

Image 10

Deployment of the solution

The solution is deployed by PowerShell, both PnP via cmdlets (Pattern & Practices), and also by CSOM code.

Image 11

  • All * .js scripts and * .html files are deployed to the root site of the site collection, in the style library, via theAdd-SPOFileorder. The advantage of this command is that it automatically creates the folder hierarchy if it does not already exist. Also use the “-Checkout” parameter … to archive the file after adding. Notice that for better performances, don’t use the style library to store files, prefer a CDN instead.
  • Only Office UI Fabric CSS are loaded from an external URL.
  • Injecting JavaScript in all pages is done via theAdd-SPOJavaScriptBlockcmlet. Under the hood, a custom action is used to include the script in every page. As well tell you right away, the parameter “-Sequence” has absolutely no effect and can not guarantee the file loading order in the page (that’s why we prefer using Require JS for this).
  • It is not possible to mix PnP cmdlets and CSOM code. For example, if you use the result of theGet-SPOContextcmdlet to get a SharePoint context and pass it to a CSOM method, it will not work (you will have an error of object casting).
  • When using SharePoint CSOM, prefer to load the assemblies from the GAC via theAdd-Typecommand (you must specify the FQDN of the assembly). Remember, these are installed via the SDK SharePoint Online Client Components.

 For the original copy of this blog in French please visit here

About the Author:

Franck

Working as a SharePoint specialist for 5 years now, I’m very specialized in intranet and portal solutions with this platform. My day-to-day role is to design and build solutions that meet expectations while leveraging the maximum possibilities of the platform. I’m also very concerned by agile methodologies especially Scrum to understand and organize requirements before and during the implementation.Through my speeches and articles, I want to share my knowledge according to my reality on the ground. Franck has been a Microsoft MVP for Office Servers and Services since 2016.

Follow Franck on Twitter: @FranckCornu 

Similar content from ESPC: 

  1. Office UI Fabric Icons for SharePoint Developers

  2. Make SharePoint SASSy

Programme -launch -graphic

Share this on...

Rate this Post:

Share: