Extend SharePoint capabilities easily with simple JS snippets
Sometimes, a useful SharePoint extension does not need any server-side code. In these cases, a simple JS snippet is sufficient.
To demonstrate an easy way to deploy SharePoint customizations, I will take a really simple case but quite useful for end-users.
from latter upgrades of SharePoint 2013, right-click on the name of a file (in default views) pops up the Edit Control Block. Which is pretty intuitive but has the serious drawback of overriding the standard browser right-click menu, and a particular interesting feature frequently asked.
As a SharePoint consultant, I often hear from my customers :
“I don’t want this file to open in-place in my current browser window, can’t I have a ‘Open in new tab’ link as I have it everywhere else with my browser ?”
There is a convenient way to achieve that, Add this link in the ECB menu. This must be done through custom actions.
Wait…, you mean I have to deploy a WSP to have that single link ?
What do we have to do ?
- Provision a JS file on the SharePoint that contains all the needed code
- Add a script link custom action to the site collection that makes all the pages of the site collection references our script file
- Add the proper custom action in the Edit Control Block that calls our JS function
The (very complex) code
var YPCode = YPCode || {}; YPCode.Utils = YPCode.Utils || {}; YPCode.Utils.openInNewTab = function (url) { var win = window.open(url, '_blank'); if (win) win.focus(); };
It opens the specified URL in a new window (a new tab) and focuses on that tab
The PnP cmdlets used here :
- Add-PnPFile to provision the .js file
- Add-PnPJavaScriptLink to reference our JS file in every pages of the site collection (can also be scoped to a single web)
- Add-PnPCustomAction to provision the custom action to all lists (by its definition type id)
Our own customization cmdlet
[CmdletBinding()] Param ( [Parameter(Mandatory=$True, HelpMessage="The site collection relative URL of the site assets library (without the starting /)")] [string]$SiteAssetsUrl, [Parameter(Mandatory=$False)] [int]$ListBaseTemplate=101, [Parameter(Mandatory=$False)] [string]$JsFileName ) # Default values $defaultJsFileName = "openInNewTab.js" $defaultScriptLinkName = "SLOpenInNewTab" $defaultCustomActionName = "OpenInNewTabCustomAction" $defaultCustomActionTitle = "Open in a new Tab" $defaultCustomActionDescription = "Allows to open a document in a new tab" # Create the context if not already existing Try { Get-PnPContext } Catch { Write-Host "Please connect to SharePoint" Connect-PnPOnline } If (!$JsFileName) { $JsFileName = $defaultJsFileName } # Write the needed JavaScript in a local file $js = "var YPCode = YPCode || {}; YPCode.Utils = YPCode.Utils || {}; YPCode.Utils.openInNewTab = function (url) { var win = window.open(url, '_blank'); if (win) win.focus(); };" $js | Out-File $JsFileName # Get the web URL $siteCollUrl = (Get-PnPSite).Url # Upload the JS file Try { $provisionnedFile = Add-PnPFile -Path $JsFileName -Folder $SiteAssetsUrl } Catch { Write-Host The JavaScript file $JsFileName cannot be provisionned to $SiteAssetsUrl Return } Try { # Add the script link custom action $jsFileUrl = $siteCollUrl + "/" + $SiteAssetsUrl + "/" + $JsFileName $result = Add-PnPJavaScriptLink -Name $defaultScriptLinkName -Scope Site -Url $jsFileUrl # Add the custom action $result = Add-PnPCustomAction -Name $defaultCustomActionName -Title $defaultCustomActionTitle -Description $defaultCustomActionDescription -RegistrationId $ListBaseTemplate -RegistrationType "List" -Group "SiteActions" -Location "EditControlBlock" -Url "javascript:YPCode.Utils.openInNewTab('{ItemUrl}');" -Scope Site } Catch { Write-Host The custom actions cannot be added to the target site }
Execute this powershell command and that’s it! You have implemented a simple customization to SharePoint.
The advantages:
- No solution package deployment (no downtime, no need for maintenance window)
- Done using CSOM (remotely), you can execute this command from any host able to reach your SharePoint site
- As valid On-Premises as Online
You can now reuse this technique to deploy any customizations implemented in JavaScript (simple or more complex ones).
I hope it will give you ideas for your future customizations.
See you soon !
Yannick