JS Link – Highlighting a Row with CSR

One conditional formatting scenario in SharePoint 2010 and SharePoint Designer 2010 was to highlight a row in a list view based on a rule: data within the item/row. SharePoint Designer 2013 unfortunately does not have the same design view available, so we need to use some relatively simple code to get the same results. This article discusses one method to get the same results using SharePoint 2013 with Client-Side Rendering (CSR) and the JS Link web part property.

Referring back to a few of my other posts you can get an idea of the general approach using CSR here:

When creating the JavaScript file this time we aren’t doing any Field or Item overrides, but we are using the PostRender functionality:

image

OverrideCtx.OnPostRender = {

As the name describes, we’re tweaking the page output after the rest of the page has been rendered. Using Field overrides we could alter the formatting of text, but not cells and wouldn’t have access to the row either. Using the Item override we could build the row from scratch and highlight the row, but it would take a lot more work rebuilding the view when we can just use the PostRender method to tweak the existing view.

image

I won’t get into all the JavaScript details but want to highlight what’s important to replicate this functionality on your own. The code essentially steps through each item/row in the table and runs the logic on each item.

There are only a few snippets you need to customize to fit your scenario:

if (listItem.Priority == “(1) High”) {

The code above is your condition / rule. ‘Priority’ is the column you’re checking the value on – remember that ‘Priority’ is the internal name of the column. You can use any column that’s included in the view for your rule criteria.

row.style.backgroundColor = “rgba(255, 0, 0, 0.5)”;  //red

This (above) is setting the row background color. You can set whichever color you need. You can have multiple rules checking different rows and applying various colors if you wish.

OK! Once the JavaScript is written and uploaded to the site (see other posts for details) and the JS Link property is set, if everything is working the list should now show a highlighted row for data that matches the rule:

image

Using the PostRender approach makes highlighting an entire row pretty easy. If you wanted to highlight a specific cell, it would be possible but would take some more code (we’ll show that another time) to get the right column selected. It’s not as easy as just calling out the column/field name. Depending on what you’re trying to accomplish on the cell/field level, that kind of change might be easier using the Field override.

Thanks again to Jon Campbell (MS), Raymond Mitchell and Phil Jirsa for hammering through much of the JavaScript details on this one. Jon clued us into some of these JS Link innerds back when he was on the SharePoint team. 🙂

24 comments

  1. Great post, Wes! Everything is working exactly as you described. Can you have OverrideCtx.OnPostRender call two functions? I’ve tried a few variations with no success – any insight would be much appreciated.

  2. Hey Wes,

    I am trying to reproduce this example and seem to not be getting the same result.

    I have referenced in JS link as ~SiteAssets/Javascripts/priority.js
    with this code in priority.js:


    (function () {
    var overrideCtx = {};
    overrideCtx.Templates = {};

    overrideCtx.OnPostRender = [
    HighlightRowOverride
    ];

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);

    })();

    function HighlightRowOverride(inCtx) {

    for (var i = 0; i < inCtx.ListData.Row.length; ++i) {
    var listItem = inCtx.ListData.Row[i];

    var iid = GenerateIIDForListItem(inCtx, listItem);
    var row = document.getElementId(idd);

    if (listItem.Priority == "(1) High") {
    if (row != null)
    row.style.backgroundColor = "rgba(255, 0, 0, 0.5)"; //red
    }

    }

    inCtx.skipNextAnimation = true;
    }

    Do you mind spreading some light on what I could be doing wrong?

    Thanks,

    -Link

  3. I would just like to add, in order for the row highlighting to persist after column sort on O365 Sharepoint Online, the following is necessary:

    //If sort is called, re-highlight rows
    _spBodyOnHashChange = function(){HighlightRowOverride(ctx);ajaxNavigate._raiseNavigate(ajaxNavigate);}

    where HighlightRowOverride is the name of your OnPostRender function. This also seems to solve the problem for search as well. From my understanding, _spBodyOnHashChange is triggered each time something after the # in the address bar is changed. In a Sharepoint list this happens during sort as it calls Inplview. If there is a better function to override to achieve the same effect I’d be glad to hear it as I’m rather new to SP and JS.

  4. Awesome post, thanks! The one issue I’m running into is this doesn’t seem to be working with IE 8. It works with all the browsers I’ve tested though. Any ideas what could be causing this? Thanks.

  5. Does anyone know why if there is some sort of race condition where you get page error on occasion page refreshed?

    TypeError: Object required
    TypeError: Object requiredTypeError: Object required

    The error occurred where I am assigning the row.
    var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
    var tr = document.getElementById(rowElementId);

  6. I am unable to get this to work, trying to get it to work on a field named Status. Here is what I am using. Can you see anything wrong?

    (function () {
    var overrideCtx = {};
    overrideCtx.Templates = {};

    overrideCtx.OnPostRender = [
    HighlightRowOverride
    ];

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);

    })();

    function HighlightRowOverride(inCtx) {
    for (var i = 0; i < inCtx.ListData.Row.length; ++i) {
    var listItem = inCtx.ListData.Row[i];

    var iid = GenerateIIDForListItem(inCtx, listItem);
    var row = document.getElementById(iid);

    if (listItem.Status == "Denied") {
    if (row != null)
    row.style.backgroudColor = "rgba(255, 0, 0, 0.5)" ; //red
    }
    }

    inCtx.skipNextAnimation = true;
    }

  7. (function HighlightRowOverride (inCtx) {

    // for each item (row)
    for (var i = 0; i < inCtx.ListData.Row.length; ++1) {

    var listItem = inCtx.ListDasta.Row[i];

    var iid = GenerateIIDForListItem(inCtx, listItem);

    var row = document.getElementId(iid);

    if (listItem.Progress =="Good"
    if (row !=null)
    row.style.backgroundColor = "rgba (255, 0, 0, 0.5)"; //red
    }

    }
    inCtx.skipNextAnimation = true;
    }
    So I can not get this to function. I know the page is connecting because I can get other javascript to work. Can anyone shed some light on to why this isn't working for me? Here is the code I copied down. Did I miss anything?

  8. Hi Wes! Thank you for your post.
    I think using the Item override is a better approach than using the PostRender method.
    You can avoid rebuilding the row from scratch by using the RenderItemTemplate(ctx) function like this:

    Item: function () {
    var itemHtml = RenderItemTemplate(ctx);
    return itemHtml.replace(“<tr", "<tr style='background-color:lightblue'");
    }

    Let me know if this solution works for you.

    My blog: http://mariagraziamerlo.com/

  9. would you please help me with these question? I have a short term contract at a company . The guy without SharePoint background asked me to create SharePoint javascript file to highlight SharePoint list column field. At this company, they have a tool for me to create a javascript, I have to work at home using my own computer. Then this guy blames that I violate the law of intellectual property. How come? Do you know anything about his? Is this kind of javascript is OOTB SharePoint javascript file? How come an OOTB SharePoint javascript custom file that highlight a SharePoint list column field is an IP (intellectual property) issue?

    For above Javascript code to highlight SharePoint list, is it OOTB? Is it also an IP issue?

  10. Can anyone show the proper script for: “You can have multiple rules checking different rows and applying various colors if you wish.” Any help is greatly appreciated.

  11. hi, I have a list using default style and it is using grouping. I want to add a code using JS link in order to change the style to shaded but without changing the default style (because I dont want to loose the quick search box from the view), How can I do that? thank you for your help. How do I add a JS link.

  12. Hello! I was wondering if you ever posted your newest post revisiting highlighting using conditionals but so that it only highlights a cell and not the entire row. I was able to properly follow your guide to highlight the row that I need but I need/want to modify to just highlight the cell. If not, would you mind commenting on your thought process to achieve this? Thank you so much!

    1. Dave, I haven’t followed up on that one specifically. It depends on what you’re trying to do. Generally if I need to make a change to something in a particular cell I’ll just use a Field override and tweak the HTML, CSS, or whatever needs to be tweaked rather than handing it with jQuery and cell properties. What are you trying to do?

  13. I am running into issues getting my web part to recognize my JS Code. I have the JSLink referencing the SiteAssets library where I have my JS file saved. Here is my code. The field I am basing my condition on is called RenewalNeeded and it is a choice field – either Yes or No. Any ideas?

    (function () {

    var overrideCtx = {};
    overrideCtx.Templates = {};

    overrideCtx.OnPostRender = [
    HighlightRowOverride
    ];

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);

    }) ();

    function HighlightRowOverride (inCtx) {

    // for each item (row)
    for (var i = 0; i < inCtx.ListData.Row.length; ++i) {
    var listItem = inCtx.ListData.Row [i];

    var iid = GenerateIIDForListItem(inCtx, listItem);
    var row = document.getElementById(iid);

    if (listItem.RenewalNeeded == "Yes") {
    if (row != null)
    row.style.backgroundColor = "rgba(255, 0, 0, 0.5)"; //red
    }
    }

    inCtx.SkipNextAnimation = true;
    }

    1. Joe, did you figure this out? Or still stuck? Initial thoughts: Do you know if the code is running at all? (file in the right place, JSLink property set correctly, etc.) I usually test by using a JavaScript alert. If that’s all working the next thing I’d look at is the value of the choice field. Off the top of my head I’m not sure that it actually contains the “Yes” and “No” values or if its something like “0” or “1”. Next thing to verify would be internal field names. Let me know. 🙂

  14. I’m not able to replicate the results. Here’s my code
    function HighlightRowOverride (inCtx)
    {
    for(var i=0; i < inCtx.ListData.Row.length; i++) {
    var listItem = inCtx.ListData.Row[i];

    var iid = GenerateIIDForListItem(inCtx, listItem);
    var row = document.getElementById(iid);

    if(listItem.Marked == "Rechazado")
    {
    row.style.backgroundColor = "rgba(4,92,8,0.1)";
    }
    }
    inCtx.skipNextAnimation = true;
    }

    What am I doing wrong?

    1. Do you have the basics covered? Are you sure the code is being called, have the right value in the JSLink property, have tested the JavaScript by using an alert(“In the code”);.
      is ‘Marked’ the correct internal name of the field you’re checking?

Leave a Reply

Your email address will not be published. Required fields are marked *