Recently I did some work for a client that required combining multiple List View Web Parts on one page, and using Client Side Rendering (CSR) to apply custom styling to each of the the various views. The site was a Team Site that had Minimal Download Strategy (MDS) enabled, and this led to some interesting challenges. The MDS feature is supposed to speed up browsing by having the client only process the differences between the current page and the new page. However, this can lead to situations where custom CSR scripts do not get executed correctly.
There is a way around this. SharePoint provides a function called
RegisterModuleInit() which you can use to tell MDS that a particular function from a particular file should always be executed.
RegisterModuleInit() takes two arguments – the path of the file that has the function to execute, and the name of the function. Now, let’s take a look at one of the popular patterns for constructing CSR template overrides, which happens to be the one I used up until this project:
We can see two things here:
1. The template overrides are defined and registered with the template manager in an anonymous self-executing function, thus there is no named entry point to register with
RegisterModuleInit(). In order to use
RegisterModuleInit() to get the code functioning properly with MDS, the template override code needs to be changed to have a named entry point.
customItem() function is defined in the global namespace. Keep in mind, for this project I was working with several template override files being loaded on the same page, many with multiple rendering override functions defined. If not handled correctly, the global namespace was going to get polluted.
So, in order to fix both of these problems, I came up with the following pattern, which I now use for all of my CSR template override scripts:
Let’s look at what’s going on in the code.
First, I register (or retrieve) my own namespace, so we can stay organized (line 1).
Second, I add a property
thisOverride (line 3). I named it generically for this example, but the name of this property should reflect the specific SharePoint asset you are applying the override to. That way many overrides can co-exist on the same page (e.g.
myNamespace.customListXOverride), and we can still use the same internal naming convention for the actual override functions (e.g.
Lastly, I register the entry point function with the MDS system (line 20), and provide a fallback for non-MDS enabled sites (line 23), ensuring that the template overrides will get applied no matter what.
Notice also that the
SPClientTemplates.Utility namespace offers a function to replace URL tokens, so you can use tokens when defining the path to your override file. This allows for much greater flexibility when including the CSR script as part of a feature that may be activated on a number of sites.
So there you have it – a CSR template override pattern that is flexible enough to work on MDS enabled or disabled sites, while maintaining responsible use of the global namespace.