6

I was testing the flexibility of CSR and came across a problem which i am not able to resolve . I have created a list which contains product details like Total Sales and Sales Target . I am trying to achieve the below requirement .

  1. Conditionally populate Sales Progress column by overriding Templates.Fields

  2. Use OnPostRender to highlight the row based on the previous conditionally populated value.

I was able to conditionally populate the sales progress column. But in PostRender function , rows[i]["Sales_x0020_Progress"] is still empty,hence row highlighting function is not working. Seems it is not working with the new ctx.However if i try to highlight rows based on an already existing column it is working(which is not conditionally populated on the fly).

Code :

(function () {
    var overrideCurrentContext = {};
    overrideCurrentContext.Templates = {};
    overrideCurrentContext.Templates.Fields = {
        'Sales_x0020_Progress': { 'View': HighlightProductRows }
    };


    overrideCurrentContext.OnPostRender = postRenderHandler;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCurrentContext);
})();

function HighlightProductRows(ctx) {
    debugger;
    var totalSalesVal =ctx.CurrentItem.Total_x0020_Sales.replace(",", "");
    var targetSalesVal =ctx.CurrentItem.Sales_x0020_Target.replace(",", "");

    if(parseInt(totalSalesVal) > parseInt(targetSalesVal))
    {
        return "On Target";
    }
    else if(parseInt(targetSalesVal)- parseInt(totalSalesVal) <=1000 )
    {
        return "Reaching Target";
    }
    else
    {
        return "Long way to target !";
    }
}

function postRenderHandler(ctx)
{
    debugger;

    var statusColors =  {
        'Long way to target !' : '#FFF1AD',
        'Reaching Target' : '#FFD800',
        'On Target' : '#01DF3A'
    };

    var rows = ctx.ListData.Row;
    for (var i=0;i<rows.length;i++)
    {
        debugger;
        var status = rows[i]["Sales_x0020_Progress"];
        var rowId = GenerateIIDForListItem(ctx, rows[i]);
        var row = document.getElementById(rowId);
        row.style.backgroundColor = statusColors[status];
    }
}

Thanks,
Priyaranjan

8

Template handler returns the HTML that is to be displayed instead of the value. It doesn't actually replace the value in the context.

You should use the same way of calculating the Sales Progress value in postRenderHandler. For example, like this:

(function () {
    var overrideCurrentContext = {};
    overrideCurrentContext.Templates = {};
    overrideCurrentContext.Templates.Fields = {
        'Sales_x0020_Progress': { 'View': HighlightProductRows }
    };


    overrideCurrentContext.OnPostRender = postRenderHandler;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCurrentContext);
})();

function AnalyseSalesValues(totalSalesVal, targetSalesVal) {

    if(parseInt(totalSalesVal) > parseInt(targetSalesVal))
    {
        return "OnTarget";
    }
    else if(parseInt(targetSalesVal)- parseInt(totalSalesVal) <=1000 )
    {
        return "Reaching";
    }
    else
    {
        return "LongWay";
    }

}

function HighlightProductRows(ctx) {

    var totalSalesVal =ctx.CurrentItem.Total_x0020_Sales.replace(",", "");
    var targetSalesVal =ctx.CurrentItem.Sales_x0020_Target.replace(",", "");

    var displayHtmls =  {
        'LongWay':'Long way to target !',
        'Reaching':'Reaching Target',
        'OnTarget':'On Target'
    };

    return displayHtmls[AnalyseSalesValues(totalSalesVal, targetSalesVal)];
}

function postRenderHandler(ctx)
{
    var statusColors =  {
        'LongWay' : '#FFF1AD',
        'Reaching' : '#FFD800',
        'OnTarget' : '#01DF3A'
    };

    var rows = ctx.ListData.Row;
    for (var i=0;i<rows.length;i++)
    {
        var totalSalesVal =rows[i]["Total_x0020_Sales"].replace(",", "");
        var targetSalesVal =rows[i]["Sales_x0020_Target"].replace(",", "");
        var status = AnalyseSalesValues(totalSalesVal, targetSalesVal);
        var rowId = GenerateIIDForListItem(ctx, rows[i]);
        var row = document.getElementById(rowId);
        row.style.backgroundColor = statusColors[status];
    }
}

More details about CSR for list views:

Also I would recommend using Cisar (if not yet) for creating CSR customizations, it simplifies the process a lot:

Disclaimer: I'm the author of both the article and the Cisar tool.

  • 1
    awesome work with Cisar. Makes CSR customizations a breeze :) – Akhoy Mar 7 '16 at 9:50
  • Thanks a lot Andrey . That worked like a charm ! I was under the assumption that Template.Fields override each row one by one and renders the new html as a whole at the end of the loop . Once the PostRender is called I believed that the newly rendered view will be used when "ctx.ListData.Row" is called . Is there any way we can get the new view within the ctx ? – Priyaranjan KS Mar 7 '16 at 10:17
  • the new view is rendered into DOM, nowhere else. you can get it from DOM. – Andrey Markeev Mar 7 '16 at 13:20

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.