Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)
With the display templates feature in SharePoint 2013, you can highly customize the look of search using HTML, JavaScript, and jQuery. It turns out there are a lot of helper functions to make your life easier in the out-of-the-box scripts. Unfortunately, there is not a lot of documentation out there on how to get started aside from looking at the code of OOTB display templates. You can also find quite a bit by looking at the debug versions of the scripts Search.cbs.debug.js and Search.clientcontrols.js.Meet ctx
When it comes to display templates, ctx is your content object for your display template. With this object, you can get access to managed properties, the number of results, and DOM elements that make up your display template. Your display template will have a reference to ctx automatically and you will need to pass it to many of the methods to get access.Accessing the Current Item
Now that you have met ctx, you can use it to do a number of actions. Use this in your item display templates and hover panels.ctx.CurrentItem
This gives you access to all of the managed properties that have been set in the ManagedPropertyMapping element. See below for the syntax to request the values.
Get the index of the current item
var index = ctx.CurrentItemIdx;
Accessing Managed Properties
The basics of retrieving values of managed properties is accessing managed properties. You can do this in two ways by using the managed property name or the display name in the ManagedPropertyMapping element of the display template. You’ll find your managed properties typically in a format like the one below with the display property on the left and the managed property name on the right. The value in brackets is optional and is used by the Content Search web part and it's what the web part shows in the property mapping section as a label.'Line 1'{Line 1}:'Title'
Get Property Value by Managed Property Name
ctx.CurrentItem.LastModifiedTime
_#= ctx.CurrentItem.LastModifiedTime =#_
var line4value = $getItemValue(ctx, "Line 4");
Useful Properties
There are a number of properties that might be useful to you if you plan on working with the JavaScript object model. For example, add the following to your ManagedPropertyMapping element to get the id of the list, list item id, and site collection URL.
'ListItemID':'ListItemID','ListID':'ListID','SPSiteUrl':'SPSiteUrl'
var listId = ctx.CurrentItem.ListID;
Get the list item id
var listItemId = ctx.CurrentItem.ListItemID;
Get the site collection URL
var siteCollectionUrl = ctx.CurrentItem.SPSiteUrl;
Get the file extension
This lets you get the file extension of the current item. Many of the helper functions use this to determine the type of document.ctx.CurrentItem.FileExtension
Including External Scripts and Style sheets
Since display templates are just HTML and JavaScript, you may want to reference external script files such as jQuery. You can also reference CSS files as well. You need to put these references in a <script> element block of your display template.Include an external script
$includeScript(this.url, "~sitecollection/_layouts/15/reputation.js");
You can reference external scripts using a relative URL as shown
above. This example pulls the script out of the current site
collection. The first parameter to $includeScript is always this.url.
$includeScript(this.url, https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.0.min.js);
You can also load scripts using SP.SOD as well if you prefer. Some recommend this approach over $includeScript as it is supposed to be synchronous where $includeScript is not.
Including a style sheet (CSS)
$includeCSS(this.url, "~sitecollection/site/library/mycustom.css");
Key Building Blocks
When it comes to working with display templates, many of the things that you need to do must be executed after the rest of the script has rendered. This especially applies for anything that modifies the DOM. Refer to the four tips for using jQuery post for more details. We use Post Render Callbacks to execute code after the display template is done rendering. Think of these as your jQuery equivalent to $(document).ready(). There are two ways to make this happen. The first is ctx.OnPostRender.push().
ctx.OnPostRender = [];
ctx.OnPostRender.push(ctx, function () {
// do something
});
If you look at the out-of-the-box templates, you'll see them executed both ways. I tend to prefer the latter technique.AddPostRenderCallback(ctx, function () { // do something });
Get a ClientContext object
Srch.ScriptApplicationManager.get_clientRuntimeContext();
Working with the DOM
You'll often need to keep track of some element Ids when working with display templates. A common practice is to generate a unique base id for the containing div element and then appending strings to those ids for child elements. This often happens at the begging of every display template and then the markup references these ids. Let's look at some examples.Creating a unique element id for a child element
var id = ctx.ClientControl.get_nextUniqueId();
var itemId = id + Srch.U.Ids.item;
<div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="DefaultItem" class="ms-srch-item" onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_">
ctl00_ctl53_g_f59f896a_d82a_4957_acea_90abc7a9b86e_csr1
Getting the id of the div of the display template
ctx.ClientControl.get_id();
Utility Functions
You'll find a number of useful functions in the Srch.U object for everything from checking for null to manipulation of strings. A lot of this overlaps with jQuery but there are some other search specific functions. In the out-of-the-box display templates you'll sometimes see these methods referenced with Srch.U or with an alias using the $ sign. Take a look at our first example.Checking for null
if (!$isNull(ctx.ClientControl))
{
// do something
}
if (!Srch.U.n(ctx.ClientControl))
{
// do something
}
if (!$isEmptyString(ctx.CurrentItem.DisplayAuthor)) { }
Checking if an array is empty
if ($isEmptyArray(myArray)) { }
Getting an array from multi-value fields such as author
var authors = Srch.U.getArray(ctx.CurrentItem.DisplayAuthor);
Check if the item is a web page
ctx.CurrentItem.csr_ShowViewLibrary = !Srch.U.isWebPage(ctx.CurrentItem.FileExtension);
Get a friendly name for a file extension
Srch.U.getFriendlyNameForFileExtension(ctx.CurrentItem.FileExtension);
Get the Display Name from an author field
var author = Srch.U.getDisplayNameFromAuthorField(ctx.CurrentItem.AuthorOWSUSER);
Setting the icon
ctx.CurrentItem.csr_Icon = Srch.U.getIconUrlByFileExtension(ctx.CurrentItem);
Get the number of items
ctx.ClientControl.get_numberOfItems();
Determine if the host is SharePoint Foundation
if (!Srch.U.isSPFSKU()) { }
Formatting
The Srch.U class has a number of methods that make formatting values easier. Besides just the basic formatting, it has formatting methods for numbers, dates, and file sizes that are more human readable such as display "5 MB" instead of "5,000,000 bytes". These method are locale aware so they should display your data in the correct format for the user.Formatting the date with a short pattern
Srch.U.toFormattedDate(ctx.CurrentItem.Write, 'ShortDatePattern');
Formatting numbers
Srch.U.toFormattedNumber(value, 3);
Format the number using approximations
Srch.U.toFriendlyNumber(value);
Format file sizes
Srch.U.toFileSizeDisplay(ctx.CurrentItem.FileSize, false);
Formatting a string
var myString = String.format('Hello World {0} {1}', value1, value2);
Truncate a URL
Srch.U.truncateUrl(ctx.CurrentItem.Path, 40);
Trim a string
Srch.U.getTrimmedString(string, 40);
Trim Spaces
Srch.U.trimExtraSpaces(string);
Localization
Display templates have built-in support for providing localization. It uses a system of resource dictionary stored in JavaScript files located in culture specific folders. Each culture specific folder contains a file CustomStrings.js. You can use this file or include your own.Registering a resource dictionary
If you look inside CustomStrings.js you will see the syntax of adding resources using a simple array with $registerResourceDictionary.
$registerResourceDictionary("en-us", {
"sampleCustomStringId": "Sample custom string",
"rf_RefinementTitle_ManagedPropertyName": "Sample Refinement Title for ManagedPropertyName"
});
Many out-of-the-box templates load a resource file automatically using the statement below. If not, you can add it yourself or modify it if you are using a different resource dictionary.
$includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
Using a resource in your display template is quite easy using $resource. It's a good idea to make use of $htmlEncode to encode it before writing it.
_#= $htmlEncode($resource("sampleCustomStringId")) =#_
I am trying to implement the Srch.U.toFormattedDate(ctx.CurrentItem.Write, 'ShortDatePattern'); in my display template but I dont how or where to put it in the template. Any guidence would be appreciated
ReplyDelete