0

I have a *.js to color code my rows according to the value of the column Status. It is working very fine UNLESS one filters any column and views/edits an item. After exiting the item view, the following error occurs:

TypeError: Unable to get value of the property `style`: object is null or undefined

It seems that the last row (see my full code below) row.style.backgroundColor = statusColors[status]; does cause the error.

Is there any alternative to OnPostRender?

SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
  OnPostRender: function(ctx) {

    var statusColors =  {
        'Accepted' : '#ccff99',  
        'Superseded' : '#ffb366',
        'Pending' : '#ffff66',
        'Delivered' : '#4bb84f',
        'Rejected' : '#ff6666'
    };

    var rows = ctx.ListData.Row;
    for (var i=0;i<rows.length;i++)
    {
        var status = rows[i]["Status"];
        var rowId = GenerateIIDForListItem(ctx, rows[i]);
        var row = document.getElementById(rowId); 
        row.style.backgroundColor = statusColors[status];
    }   
  }
});
  • Are you overriding the View or item or none of them in your template overrides? Your logic can possbily be moved to the item override function where you set the background colout accodring to the status. – HarryB Mar 29 '16 at 10:28
3

You can replicate the issue by placing two views in a Page. OnPostRender is applied to all.

One View will color correct, the other will give the .style is undefined error

It is because the ctx object is a (window) global Object
which SharePoint (ab)uses for all CSR transformations.

So on first run all is fine

Then SharePoint processes the next View and thus 'destroys' your precious ctx Object from the previous View

Writing function( MYctx ) will not help, as JavaScript always passes Objects by reference

To be correct function( ctx ) is senseless, it is the same as function(), because ctx is a global

Method 1

To workaround your issue you have to store the ids in your own object, then in the OnPostRender proces your own object.

Note that OnPostRender fires on every View Refesh, coloring (already colored) TRs over and over again.

Method 2

Involves code you put in the Field render, which waits for the DOM to be painted, then applies the color. I wrote about this earlier: Highlight Sharepoint List based on condition

var iid = GenerateIID();
var daysleft = 80;
_spYield(function(){
    var row = document.getElementById(iid);
    if (daysleft < 90) row.style.backgroundColor = "lightcoral";          
},20);

Method 3

In the iCSR framework I do not use OnPostRender at all for this coloring stuff.
It is easier to insert a blank image in the Field with an onload event to color its own! parent TR, same technique I used for many years in the Calculated Column ViewMasters

Method 4

If in our case you are not dealing with multiple Views.

Your TR rows are already colored on the first run

The easiest ductape patch might be to check

  var TR=document.getElementById(row.iid);
  if (TR) TR.style.backgroundColor = color;

I have not tested this, could be MDS issues

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.