SharePoint CSR (Client Side Rendering) not updating in Cache

My last post was about client side rendering customization. I wrote how to change the UI of a listview based on some values of the SharePoint list item. I realized that changes i made in my JSLink file are displayed but sometimes they are only available after a hard refresh (STRG+F5). When i first navigate to the list it looks like this:

cond_1

After hitting STRG+ F5 it looks like i was expecting it to look:

cond_10

What is the reason and what can i do?

Ok first the reason ist MDS – Minimal Download Strategy. There is a really cool post which explains it pretty good. And of course i got it working thanks to this great post of Wictor Wilén.

What can i do?

I just changed my code a little bit. The important steps are the following:

  • Create a Namespace like ILS
  • Define the Functions and Templates inside the namespace
  • Implement a register function for MDS and non-MDS Sites

The background is explained in the posts i linked in my post, but to cut a long story short, the namespace has to be registered correctly to work in MDS, cause MDS just reloads the Delta and contains something like a garbage collector, which removes global variables. So we register our Namespace everytime and make sure that it will load our customization with each page load.

My example can be downloaded here.

[sourcecode language=”csharp”]
Type.registerNamespace(‘ILS’)
ILS.Demos = ILS.Demos || {};
ILS.Demos.Templates = ILS.Demos.Templates || {};
ILS.Demos.Functions = ILS.Demos.Functions || {};

ILS.Demos.Functions.CreateDateFormat = function(ctx)
{
//Convert the CreateDate into a number with getTime()
//ATTENTION: We Split by using ‘/’ if you turn to another language setting it might not working!
var CreateDate = new Date(ctx.CurrentItem.CreateDate.split(‘/’)[2],ctx.CurrentItem.CreateDate.split(‘/’)[0]-1,ctx.CurrentItem.CreateDate.split(‘/’)[1]).getTime();

var today = new Date();
today.setHours(0,0,0,0);

var todayNo = today.getTime();

//Compare and react
if(CreateDate == ‘undefined’ || !CreateDate)
{
return ctx.CurrentItem.CreateDate;
}
else if(CreateDate < todayNo) { return "“+ctx.CurrentItem.CreateDate+”“;

}
else if(CreateDate == todayNo)
{
return ““+ctx.CurrentItem.CreateDate+”“;
}
else
{
return ctx.CurrentItem.CreateDate;
}
}

ILS.Demos.Functions.PriorityFormat = function(ctx)
{
var priorityValue = ctx.CurrentItem.Priority;

if(priorityValue == ‘High’)
{
return ““+ctx.CurrentItem.Priority+”“;
}
else
{
return ctx.CurrentItem.Priority;
}

}
ILS.Demos.Functions.PercentCompleteFormat = function(ctx)
{
var returnvalue = ‘

‘+ctx.CurrentItem.PercentComplete+’

‘;
return returnvalue;

}

ILS.Demos.Functions.HighlightRowOverride = function(ctx)
{
for(var i=0; i < ctx.ListData.Row.length; i++) { var listItem = ctx.ListData.Row[i]; var iid = GenerateIIDForListItem(ctx, listItem); var row = document.getElementById(iid); if(listItem.Marked == "Yes") { row.style.backgroundColor = "rgba(4,92,8,0.1)"; } } ctx.skipNextAnimation = true; } ILS.Demos.OnPostRender = [ILS.Demos.Functions.HighlightRowOverride]; ILS.Demos.Templates.Fields = { "Priority": {"View": ILS.Demos.Functions.PriorityFormat }, "PercentComplete": {"View": ILS.Demos.Functions.PercentCompleteFormat }, "CreateDate": {"View": ILS.Demos.Functions.CreateDateFormat } }; ILS.Demos.Functions.RegisterField = function () { SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ILS.Demos) } ILS.Demos.Functions.MdsRegisterField = function () { var thisUrl = _spPageContextInfo.siteServerRelativeUrl + "/_catalogs/masterpage/Display Templates/cond_formatting.js"; ILS.Demos.Functions.RegisterField(); //That's an important step when MDS is active RegisterModuleInit(thisUrl, ILS.Demos.Functions.RegisterField) }; //Starting //If _spPageContextInfo is available the MDS is activated, we have to register our function if (typeof _spPageContextInfo != "undefined" &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; _spPageContextInfo != null) { ILS.Demos.Functions.MdsRegisterField(); } else { //MDS is not activated, we register our Functions ILS.Demos.Functions.RegisterField(); } [/sourcecode] That's it. I know it is not well documented on the web, but for me the post of Wictor helped a lot and just trying. If you have more ideas or improvements please let me know.

The article or information provided here represents completely my own personal view & thought. It is recommended to test the content or scripts of the site in the lab, before making use in the production environment & use it completely at your own risk. The articles, scripts, suggestions or tricks published on the site are provided AS-IS with no warranties or guarantees and confers no rights.

About Karsten Schneider 312 Articles
Consultant for Microsoft 365 Applications with a strong focus in Teams, SharePoint Online, OneDrive for Business as well as PowerPlatform with PowerApps, Flow and PowerBI. I provide Workshops for Governance & Security in Office 365 and Development of Solutions in the area of Collaboration and Teamwork based on Microsoft 365 and Azure Cloud Solutions. In his free time he tries to collect tipps and worthy experience in this blog.

3 Comments

  1. Hi Karsten, I have tried using your tips to implement the conditional formating but after spending several hours, I am unable to make it work. It would be nice if I can share it with you via Lynx or anything else to get it working. Appreciate any help you can provide for your time and effort.

    Regards,
    Vijay

  2. Karsten, your code works beautifully for me. There is one item that has eluded me. When I filter a list and manually refresh I get the following error: TypeError: Cannot read property ‘style’ of null.
    I am guessing that this is caused by the filter process throwing the row id off. I have not been able to figure out how to resolve this issue. Would you be able to provide me with guidance?

    Thank you very much for your helpful code and assistance.

  3. Hi Karsten,

    I tried both your codes for applying Conditional formatting to my list in Sharepoint 2013 but none of them worked properly.

    Below is the Code – Could you please let me know what wrong am I doing which is restricting the conditional formatting to apply

    (function () {
    var condFieldCtx = {};

    // Define template variable
    condFieldCtx.Templates = {};

    // Define your required fields and functions to call in each case.
    // In our case the field is Progress
    // Override Function is PatientProgressViewTemplate
    condFieldCtx.Templates.Fields = {
    “Impact”: {“View”: ImpactFormat},
    “Likelihood”: {“View”: LikelihoodFormat},
    “Severity”: {“View”: SeverityFormat}
    “Level of Control”: (“View”: LevelofControlFormat)
    };

    //conditional formatting for a complete row comes here
    condFieldCtx.OnPostRender = [HighlightRowOverride];

    // Register the template override with SP2013
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(condFieldCtx);

    })();

    function ImpactFormat(ctx)
    {
    var impactValue = ctx.CurrentItem.Impact;

    if(impactValue == ‘1. Negligible’)
    {
    return “”+ctx.CurrentItem.Impact+””;
    }
    else

    if(impactValue == ‘2. Minor’)
    {
    return “”+ctx.CurrentItem.Impact+””;
    }
    else

    if(impactValue == ‘3. Moderate’)
    {
    return “”+ctx.CurrentItem.Impact+””;
    }
    else

    if(impactValue == ‘4. Major’)
    {
    return “”+ctx.CurrentItem.Impact+””;
    }
    else

    if(impactValue == ‘5. Critical’)
    {
    return “”+ctx.CurrentItem.Impact+””;
    }
    else
    {
    return ctx.CurrentItem.Impact;
    }

    }

    function LikelihoodFormat(ctx)
    {
    var likelihoodValue = ctx.CurrentItem.Likelihood;

    if(likelihoodValue == ‘1. Rare’)
    {
    return “”+ctx.CurrentItem.Likelihood+””;
    }
    else

    if(likelihoodValue == ‘2. Unlikely’)
    {
    return “”+ctx.CurrentItem.Likelihood+””;
    }
    else

    if(likelihoodValue == ‘3. Possible’)
    {
    return “”+ctx.CurrentItem.Likelihood+””;
    }
    else

    if(likelihoodValue == ‘4. Highly Likely’)
    {
    return “”+ctx.CurrentItem.Likelihood+””;
    }
    else

    if(likelihoodValue == ‘5. Almost Certain’)
    {
    return “”+ctx.CurrentItem.Likelihood+””;
    }
    else
    {
    return ctx.CurrentItem.Likelihood;
    }

    }

    function SeverityFormat(ctx)
    {
    var severityValue = ctx.CurrentItem.Severity;

    if(severityValue == ‘1. Very Low’)
    {
    return “”+ctx.CurrentItem.Severity+””;
    }
    else

    if(severityValue == ‘2. Low’)
    {
    return “”+ctx.CurrentItem.Severity+””;
    }
    else

    if(severityValue == ‘3. Moderate’)
    {
    return “”+ctx.CurrentItem.Severity+””;
    }
    else

    if(severityValue == ‘4. High’)
    {
    return “”+ctx.CurrentItem.Severity+””;
    }
    else

    if(severityValue == ‘5. Very High’)
    {
    return “”+ctx.CurrentItem.Severity+””;
    }
    else
    {
    return ctx.CurrentItem.Severity;
    }

    }

    function LevelofControlFormat(ctx)
    {
    var levelofcontrolValue = ctx.CurrentItem.LevelofControl;

    if(levelofcontrolValue == ‘1. No Controls’)
    {
    return “”+ctx.CurrentItem.LevelofControl+””;
    }
    else

    if(levelofcontrolValue == ‘2. Minimal Controls’)
    {
    return “”+ctx.CurrentItem.LevelofControl+””;
    }
    else

    if(levelofcontrolValue == ‘3. Some Control’)
    {
    return “”+ctx.CurrentItem.LevelofControl+””;
    }
    else

    if(levelofcontrolValue == ‘4. Adequately Controlled’)
    {
    return “”+ctx.CurrentItem.LevelofControl+””;
    }
    else

    if(levelofcontrolValue == ‘5. Well Controlled’)
    {
    return “”+ctx.CurrentItem.LevelofControl+””;
    }
    else
    {
    return ctx.CurrentItem.LevelofControl;
    }

    }

Leave a Reply to Robert Cancel reply

Your email address will not be published.


*