Azure / Office 365 / SharePoint Development / Search

How to load scripts that are required for your item display template rendering

September 21, 2017

Based on the number of questions I receive in my mailbox, I can see that display templates are still not yet forgotten. A long time ago, I wrote about how to correctly include scripts into your display templates.

Read more: Correctly including scripts into your display templates

The main issue when using the default functions (for example $includeScript) to include scripts into your templates, is that they are loading your scripts asynchronously. So, you never know when they are ready to be used. Which could be a problem when your code is dependent on that script.

In the article I wrote, I explain how to make use of the RegisterSod and EnsureScriptFunc functions to make sure the script is loaded before executing your code. This approach works great in control display templates and after your display templates rendered. Like for example, you could use the approach to make sure the display template loads jQuery and a slideshow plugin and starts cycling after the content has been rendered.

Now there is one thing which I did not yet cover in the article. That is a way to provide how you could load a script which is required for correctly rendering your item display template.

Most of the questions I received were about loading Moment.js for some advanced date rendering of the managed property values. In this article, I will show you a way to achieve this. Of course, this approach can be used for any other thing you want to achieve.

It all starts in the control display template

You might ask yourself, why the control display template? That is because this template is the first template which gets loaded so we can do the registration of the scripts in that one. Another reason is that it is much easier to develop it via the control display template. Otherwise, you would have to create a lot of script load checks and DOM manipulations to get it working.

The first step is to register your script to load. This can be done like this:

Next is to write the EnsureScriptFunc function, which makes sure your registered script gets successfully loaded. One major change is that we will move all the code from the control display template into this function.

Important: you can also see that there is a AddPostRenderCallback function defined. The reason this function has been included is to support async updates.

Due to the change of placing the code in the EnsureScriptFunc function, the way to render the display template markup on the page also had to change. Instead of giving the display template control over the rendering, our code will add the HTML onto the page.

In the code, you have to make use of a placeholder element to which add the HTML markup once it is retrieved.

The following is required for the placeholder element:

Info: Add this above the AddPostRenderCallback function.

The last thing to add to the control template is the placeholder element:

Once you have all this in place, the control display template will first load the script dependency before rendering the item display template. By doing this, you can now make use of moment in the item display template. No other change is necessary for the item display template.

Sample of the item display template rendering with moment.js

Sample of the item display template rendering with moment.js

Download the templates

To make it easier I shared the display templates I created for this sample here: Item display template script dependency.

Comments

  • Pingback: Correctly including scripts into your display templates - @eliostruyf()

  • Matthew Venne

    I’m very new to the world of coding and display templates but am a long time SP administrator/architect. Last year, I wrote an item display template, based on a OOB template just adding some managed properties to display template. I got it to work out nicely after lots of banging my head on the wall, but recently I wanted to go back and add some javascript to update the color based on the property..I added a class around the property and called it in the script below

    window.onload = function()
    {
    var status_array = document.getElementsByClassName(“sefl_status”);
    var pattern = new RegExp(“Effective”);
    for (var i=0; i < status_array.length; i++)
    if (pattern.test(status_array[i].innerHTML)===true)
    {
    status_array[i].style.color = "green"
    }
    }

    When I called this script in the item display template and the control template, it runs…but there is a slight delay where I see the color actually change on the page..immediately after changing…any ideas?

    • The code you show here is something you can solve without any delay as you do not require another script to load. The only thing you require it seems is a status value. All you have to do is implement the logic in your item display template to set the style color to green.

      • Matthew Venne

        Thank you! I have the sefl_status class tagged surrounding my managed property I want this to apply to.

        One quick question, I’ve noticed that when I change the query on the search page the JavaScript doesn’t fire for the new query. Only on the initial query. For example I search for the word “content”
        And the status sets green when it is equal to “Effective”. If I change the query to something else, the results display but the color of the status is the default color. This’t a CSWP or CQWP but a custom Search Results page.

        • When new results + content is rendered on the page, it updates the HTML. So normally it should also update your status colors. If not, there might be something wrong with the checks in your display template.