Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Posted Wednesday, February 26, 2014 10:58 AM by CoreyRoth

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.  This post today serves as a guide to go along with my upcoming Display Templates talk (#SPC3000) at SharePoint Conference 2014.

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.

DisplayTemplateDebuggerCtxCurrentItem

Get the index of the current item

var index = ctx.CurrentItemIdx;

An item display template gets called for each result you have.  This property is useful to determine if you are on the first or last result.

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'
ContentSearchPropertyMappings

Get Property Value by Managed Property Name

ctx.CurrentItem.LastModifiedTime

Your managed properties that you define in the ManagedPropertyMappings will show up as typed properties that you can access directly from the ctx object.  The example above display the last modified time.  Remember you can display a field from inside the HTML markup with the _#= =#_ markup.

_#= ctx.CurrentItem.LastModifiedTime =#_

Get Property Value by Display Name

var line4value = $getItemValue(ctx, "Line 4");

You can also use $getItemValue to get the value of a property using the web part display name (the value in the brackets).  This is good for the content search web part where you don't know what managed property the user has mapped to your column.  For example, in the screenshot above if I request Line 4, it will provide me the value of the Path managed property.

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'

Get the host list id

var listId = ctx.CurrentItem.ListID;

This will retrieve the GUID of the list containing the item.

Get the list item id

var listItemId = ctx.CurrentItem.ListItemID;

This will return the numeric list item id of the list item.  This returns the integer value as opposed to the GUID.

Get the site collection URL

var siteCollectionUrl = ctx.CurrentItem.SPSiteUrl;

The site collection URL is available with the SPSiteUrl managed property.  If you need access to the site (web) instead of the site collection, the process is a little bit more involved.

Get the file extension

ctx.CurrentItem.FileExtension

This lets you get the file extension of the current item.  Many of the helper functions use this to determine the type of document.

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 specify an absolute URL including those residing externally on a CDN. 

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");

Referencing a style sheet looks similar to referencing a script.

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

});

The first statement clears the array and the second one pushes your function onto it.  This means you can have multiple OnPostRender event handlers. Instead, you may want to use AddPostRenderCallback

AddPostRenderCallback(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.

Get a ClientContext object

Srch.ScriptApplicationManager.get_clientRuntimeContext();

This will return a ClientContext object for the site hosting the search component.  If you are looking to get a ClientContext object for the site hosting the search result, see this post.

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();

One of the first lines of script you will find in a display template is this one.  It generates a unique id that will be assigned to the first div element.  You'll then see another line such as this when is actually used by the first div element.

var itemId = id + Srch.U.Ids.item;

The div element uses $htmlEncode (which we'll cover below) to html encode the id.

<div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="DefaultItem" class="ms-srch-item" onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_">

What do these ids look like?  Here is an example.

ctl00_ctl53_g_f59f896a_d82a_4957_acea_90abc7a9b86e_csr1

Getting the id of the div of the display template

ctx.ClientControl.get_id();

This will return the base id of the display template.

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

}

The above use of $isNull will execute the code in the if statement if the object is not null.  The code snippet below using Srch.U.n will also do the same thing.

if (!Srch.U.n(ctx.ClientControl))

{

    // do something

}

Checking for an empty string

if (!$isEmptyString(ctx.CurrentItem.DisplayAuthor)) { }

You can use $isEmptyString or Srch.U.e to check if a string is empty.

Checking if an array is empty

if ($isEmptyArray(myArray)) { }

To determine if an array is empty $isEmptyArray.

Getting an array from multi-value fields such as author

var authors = Srch.U.getArray(ctx.CurrentItem.DisplayAuthor);

The Srch.U.getArray method is handy because it knows how to split common multi-value fields such as author.  It has a list of known delimeters such as ",#", "|", and ";".

Check if the item is a web page

ctx.CurrentItem.csr_ShowViewLibrary = !Srch.U.isWebPage(ctx.CurrentItem.FileExtension);

This method knows extensions for common page types and will return true if the extension is a page (i.e.: .aspx or .html).

Get a friendly name for a file extension

Srch.U.getFriendlyNameForFileExtension(ctx.CurrentItem.FileExtension);

This method is how search displays the word PowerPoint instead of PPTX.

Get the Display Name from an author field

var author = Srch.U.getDisplayNameFromAuthorField(ctx.CurrentItem.AuthorOWSUSER);

This function will display the author's full name properly.

Setting the icon

ctx.CurrentItem.csr_Icon = Srch.U.getIconUrlByFileExtension(ctx.CurrentItem);

This allows you to override the icon for a given item result.  You can call Srch.U.getIconUrlByFileExtension() if you want to get the icon for the given file type.

Get the number of items

ctx.ClientControl.get_numberOfItems();

You can get the number of items returned using ctx.CurrentItem.get_numberOfItems().

Determine if the host is SharePoint Foundation

if (!Srch.U.isSPFSKU()) { }

Some functionality isn't available in SPF, use this method to determine your version.

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');

By default, this will use LongDatePattern if you don't specify a date pattern. 

Formatting numbers

Srch.U.toFormattedNumber(value, 3);

This formats the number with three decimal places if you are passing it a decimal number.

Format the number using approximations

Srch.U.toFriendlyNumber(value);

This is useful for numbers in the 1,000 range and greater.  It rounds down to the nearest thousand.  For example, 52,343 will be returned as "52,000+".  If the value is greater than 100,000, it will return a value of 100,000+.

Format file sizes

Srch.U.toFileSizeDisplay(ctx.CurrentItem.FileSize, false);

This will return the file size in GB, MB, or KB.  You can optionally have it show the decimal part with the second parameter.

Formatting a string

var myString = String.format('Hello World {0} {1}', value1, value2);

String formatting is available just like you would use in C#.

Truncate a URL

Srch.U.truncateUrl(ctx.CurrentItem.Path, 40);

Want to display a truncated path like you see in the search results.  This method is how it is done.  You can specify the number of characters in length you want it with the second parameter.

Trim a string

Srch.U.getTrimmedString(string, 40);

Use this to trim a long string.  An ellipsis (...) will be added to the end of the string past the cutoff (second parameter)

Trim Spaces

Srch.U.trimExtraSpaces(string);

This method is handy to trim spaces from a 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.  

DisplayTemplateLanguageFiles 

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"

});

Loading a resource file

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

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")) =#_

See more at #SPC14

If you are interested in Display Templates, be sure and come see my talk (#SPC3000) at SharePoint Conference 2014.  We'll be using a lot of what you see in this post in the demos.

Follow me on twitter: @coreyroth

Comments

# Useful JavaScript for working with SharePoint D...

Wednesday, February 26, 2014 11:06 AM by Useful JavaScript for working with SharePoint D...

Pingback from  Useful JavaScript for working with SharePoint D...

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Thursday, February 27, 2014 2:11 PM by Kourosh

Thanks, ite awesome

# Sharepoint | Pearltrees

Tuesday, March 11, 2014 5:16 AM by Sharepoint | Pearltrees

Pingback from  Sharepoint | Pearltrees

# Friday Five - March 14, 2014

Sunday, March 16, 2014 1:43 PM by The Microsoft MVP Award Program Blog

1. CloudSix API: add cloud storage support to your app in a nutshell By Windows Phone Development

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Thursday, April 17, 2014 1:18 AM by Luc

Great help!

rf_RefinementTitle_ManagedPropertyName i working goood! but how to locale Refinement Items?

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Monday, April 28, 2014 12:56 AM by Luc

As an answer to my self: I did solve it by modifying filter_default.html display template and did use my own system for namning in the customStrings.js

then changed in outputFilter function:

var translatedRefinementName = Srch.U.$C("refinements_"+refinementName.trim(),false);

Hope it helps for other! happy coding!

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Monday, May 5, 2014 7:52 AM by Rintu

Hi Luc,

Thanks your blog is very help full,

i have one query, i am using your last comment in this blog.

facing issue in

var translatedRefinementName = Srch.U.$C("refinements_"+refinementName.trim(),false);

can you please update you explain you code.

Thanks

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Monday, June 9, 2014 1:27 AM by Karan Singh

Hi,

You have written " If you need access to the site (web) instead of the site collection, the process is a little bit more involved."

I have a requirement to get the web url where the list is. Can you please help me with that. Thanks.

# Useful JavaScript to know when working with SharePoint Display Templates

Tuesday, June 10, 2014 3:51 AM by SharePoint Blog - René Hézser

This post has some really great examples for JavaScript help ...

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Monday, June 23, 2014 2:48 AM by Sudarshan Vatturkar

I am using sharePoint 2013 Cross Site Publishing feature and catalog contents are rich type of contents where it hold html tags, images, links etc as part of content.

My observation is, when I render the content it comes as plan text and Is it possible to render rich content via search using display templates?

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Wednesday, August 6, 2014 7:11 AM by Jerry O

I have created a custom display template for the people search that includes mobile #, Phone #, manager....etc.  We are 100% in the cloud with 0365 using dir sync to synch our AD data.  The users network login name is not mapped from AD to SharePoint profile, but it is mapped into Exchange.  I would like to add the network login name into the people search results but cannot map the field into the user profile at this point.  Is there any way to grab the network login id and add it to a people search display template without having it mapped into the SharePoint user profile?

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Wednesday, August 13, 2014 10:20 AM by Brian

" If you need access to the site (web) instead of the site collection, the process is a little bit more involved." --- you mind elaborating on this?

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Friday, August 15, 2014 8:48 AM by CoreyRoth

@jerry o I don't think so.  It can only pull values from the user profile.

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Tuesday, August 26, 2014 4:35 AM by Ricky

Great overview, thank you very much!

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Thursday, January 8, 2015 6:42 AM by nitin

Great !!! Great !!! Great !!! Great !!!

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Monday, January 19, 2015 5:23 PM by Jamal

Hello this is a very helpful article. Does anyone know how to get the value of a term from it's managed property. I am typing

ctx.CurrentItem.owstaxIdCustomerx0020Applicationx0020Type but it returns me a bunch of guid crap.

# Useful JavaScript to know when working with Sha...

Wednesday, January 21, 2015 7:53 AM by Useful JavaScript to know when working with Sha...

Pingback from  Useful JavaScript to know when working with Sha...

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Wednesday, April 15, 2015 3:26 PM by Rahul

Hi,

I have code as below:

var postedOn = $getItemValue(ctx, "PublishedDate"); now Postedon Variable show descrpency if we change timezone from computer clock. How can we show correct stored date in others timezone .

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Friday, June 12, 2015 6:26 AM by Johan

HI,

this is very useful, but the item count (ctx.ClientControl.get_numberOfItems();) seems to be shared across multiple controls on a page.

I am adding more than one CSWP on a page and the counter shows the last CSWP's item count :s

Any ideas?

# SharePoint 2013 JavaScript Search files classes reference - Refinement Web Part classes in detail - Jos?? Quinto

Pingback from  SharePoint 2013 JavaScript Search files classes reference - Refinement Web Part classes in detail - Jos?? Quinto

# SharePoint 2013 Hot Links and References | Robin G??ldenpfennig

Pingback from  SharePoint 2013 Hot Links and References | Robin G??ldenpfennig

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Saturday, September 26, 2015 2:49 PM by Ruaa

please , iwant to display text item in blogg site using diplay template in SharePoint desigener 2013 but they came with HTML elemnt so how can i delet it (HTML elemnt <p><div class>)?

Text is : <div class="ExternalClass5391BFE82C6C421EAE49E1F8D0FABA77"><p>Hej alla i projektteamet Nadella. Nu pågår sprint 1 för fullt och vi sitter i skolan och jobbar. Content Search Web Part och Excel Web Access Web Part går det att förena dessa.? Vi får se.​</p></div>

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Thursday, December 3, 2015 4:43 PM by Mik

I'm new to SharePoint. I've tried leveraging Srch.U object but get a reference error that Srch is undefined. How do I create the reference for the object in the page layout?

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Wednesday, December 9, 2015 1:46 PM by Tracy

Have you encountered an issue where ctx.CurrentItem does not exist within another function?  See example below.

//This works because CurrentItem is a valid object.

ctx.CurrentItem.Path = "Something";

$.ajax({

 url: restURL,

 dataType: 'json',

 method: "GET",

 headers: { "Accept": "application/json; odata=verbose" }

 success: function (data) {

   //This does not work, because ctx.CurrentItem is null.  

   ctx.CurrentItem.Path = "Something";

 },

});

And when I try setting ctx.CurrentItem to another variable outside the scope, it will let me access the values but changes made to them do not persist outside the immediate 'success' function.  

What this means is that if I need data from a REST query as content to any of my ctx.CurrentItem property updates, I can no longer use the ctx.RenderBody(ctx) call and will have to manually create the DOM elements by-hand within the display template.  Not a huge deal, except I will miss out on handy functionality like Hit Highlighting and Best Bets.  

# Search Display Templates and JavaScript &#8211; SharePain

Thursday, March 3, 2016 2:58 AM by Search Display Templates and JavaScript – SharePain

Pingback from  Search Display Templates and JavaScript &#8211; SharePain

# re: Useful JavaScript to know when working with SharePoint Display Templates (#SPC3000)

Friday, May 19, 2017 5:33 AM by Tapas Paul

Thank you for this beautiful blog, I am new in multi lingual site and I think you can help me in one of my Issue.

I have a site which is set in French language and in a page it has refinement filters.

In the filter there is a link "SHOW MORE" and "SHOW FEWER" which is in English language, can you please guide me ,how can I change this text in their respective language which is French in my case.

Leave a Comment

(required)
(required)
(optional)
(required)