Thursday, October 15, 2015

Using "#" in SharePoint Navigation items

Morning folks, that's going to be one of my favorite blog post types - a short one :) 

Yesterday I've had to design a Help Section for our Intranet. I thought that this shouldn't be a static Word or PDF document, but instead wanted to make it a bit more dynamic and engaging to the users. That means a page or a site... whatever you choose, based on how big your Help Section would grow... and what's the current level of training of your users. I'll use a site for my solution having in mind it's easy to scale this up. So... what I want to have in there is something like this nice and modern-looking FAQ template by CodyHouse.

The functionality to click on a category (Basic) for example and automatically scroll to the respective section on the page (ul with id #basic) is what I found challenging with the current setup in SharePoint.
Instead of using a custom categories list in the page, my goal is to use the container for the Current Navigation (Quick Launch) which is already there. This will give us consistent look & feel across the whole site.

The problem I've found today is that "#" is actually not working in the links of the SharePoint navigation...if you're using Structural Navigation for your site. No matter where you insert it, on save your links will always default. To see what I mean, here's the link that I insert and save.

In the reality, I get this in the browser (all of them):

So... my solution was a quick win this time - switch to Managed Navigation for this site, create a termset for it and use Simple Links for the navigation terms. Works as a charm.

What you see...

...is what you get:


Monday, October 5, 2015

Injecting JavaScript in a SharePoint Online site collection the proper way

With recent changes in Office 365 branding guidelines, it has become significantly more difficult to insert small bits and pieces of functionality like a 10-line JavaScript, for example. I had to do this in order to bring the same global navigatoin that we use in our main site collection into the Search Center site collection (the requirement is even more difficult if you use Managed Navigation, but that's not the topic of this post).

By default, the navigation is missing from the Search Center in SPO and SharePoint 2013.
A great way to get it back is described in this post by MVP Elio Struyf. But how would you inject the JS in the whole site collection? By default, we have 7 different result pages in this site, and we plan to create more... so here are our options:

1) Insert the script in a CEWP or a Script Editor webpart - manually in each of the pages... time consuming and the need for manual adjustments arises each time you create a new results page.

2) Use custom master page for the site collection - a big No-No for SharePoint Online since a few months.

3) Build a provider-hosted app that can inject your customization :) Great video by the Office 365 PnP team, but it sounds to me like killing the fly with a hammer! 

4) Register it through another .js and forget about supportability and removal with no code... Quick & Dirty approach by Tim Ferro that I'd only ever use as a PoC.. (tested it and does the job by the way).

5) Using PowerShell! Wait, what!? Yep. After some head-banging last Friday afternoon, my friend and PowerShell guru Ivan Yankulov has reminded me that there was a pretty good cmdlet from the PnP-PowerShell project

All you need to do is... 

1) Download the project locally
2) Have WiX toolset installed (at least 3.10 if you use VS2015)
3) (Optional) Have Windows Management Framework 4.0 installed if you want to generate the cmdlet Help
4) Install the binaries (\Binaries\PnPPowerShellCommands16.msi) for SharePoint Online
5) Run PowerShell 3.0 as an admin...
6) Have a look at the AddSPOJavaScriptLink documentation.
7) Connect to your SPOnline tenant (Connect-SPOnline –Url https://yoursite.sharepoint.com –Credentials (Get-Credential)
8) Execute the command...

Let's assume I want to inject something called elementshide.js to my whole site collection. So whenever someone creates a site or a page inside, they'll get the JavaScript loaded automatically for consistent site collection-wide user experience. The key parameter is like an identifier for your script  - take a note of this if you want to remove the script reference later on :) The url is basically the path to the script (relative URL is always recommended) and then the scope could be Site for a site collection, or web for a subsite in SharePoint Online. 

 Add-SPOJavaScriptLink -key ElementsHide -url "~sitecollection/SiteAssets/elementshide.js" -Scope Site -Web https://dimitarm.sharepoint.com

9) Verify. Go to your page and view the source code... you'll have the following piece if the injection went through:

if (scriptsSrc.indexOf('/SiteAssets/elementshide.js') === -1) {
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = '/SiteAssets/elementshide.js'; 
headID.appendChild(newScript);
scriptsSrc.push('/SiteAssets/elementshide.js');
}(function(){ 


So this is it... in a little bit less than 10 steps we've managed to make our Search Center navigation show up...and we're ready for a lot more customization done this way. Hopefully the guidelines by the O365 team do not change to something even more complicated in the next months...