JSLINK is firing for one time only when the page first loads, and need to do refresh for the web page to get it firing again

sharepoint.stackexchange https://sharepoint.stackexchange.com/questions/215466

Question

I am working on a Team site collection inside SharePoint server 2016. I have the following JSLINK, which will show the sum of a column inside my list view:-

var _totalValue = 0.0;
var _totalColumn = 27;  // Specify total number of columns in list view.
var _columnIndex = 10;  // Specify the index of the column where you want to display sum values. (i.e. index for first column = 1)

(function () {

    var calculatedFieldCtx = {};  

    calculatedFieldCtx.Templates = {};

    calculatedFieldCtx.Templates.Fields = {
        "Yearof2016MLC": {
            "View": CalculatedFieldViewTemplate
        }
    };

    calculatedFieldCtx.OnPostRender = [];
    calculatedFieldCtx.OnPostRender.push(function()
    {  
        // Specify id of the list view table for which you want to display sum values. 
        var HTMLTableElement = document.getElementById("{B3D883A5-6962-47FD-BDEF-BB83FF4C78EA}-{C86BA145-8C22-47E8-938C-11B8C7F855C3}");

                var tbodyElement = document.createElement('thead');
                tbodyElement.id = "customAggWPQ";

                var trElement = document.createElement('tr');

                var tdElement;
                for(var i = 1; i <= _totalColumn; i++) {
                        tdElement = document.createElement('th');
                        tdElement.id = "tdElement" + i;
                        if( i == _columnIndex) {
                              tdElement.innerHTML = "<b>Sum= " + numberFormat(_totalValue) + "</b>";
                        }
                        trElement.appendChild(tdElement);
                }

        tbodyElement.appendChild(trElement);
        if(document.getElementById("customAggWPQ") == null) {
                HTMLTableElement.insertBefore(tbodyElement,HTMLTableElement.firstChild.nextSibling);
        }
        else {
                document.getElementById("tdElement" + _columnIndex).innerHTML = "<b>Sum= " + numberFormat(_totalValue) + "</b>";
        }
        _totalValue = 0.0;
    })

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(
        calculatedFieldCtx
    ); 
})();


function CalculatedFieldViewTemplate(ctx) {       
    _totalValue += parseFloat((ctx.CurrentItem.Yearof2016MLC).replace(',', ''));

    return ctx.CurrentItem.Yearof2016MLC;
}

var numberFormat = function(number) {
        var sDelimeter = ',';
        number = Math.round(parseFloat(number) * 100) / 100;
        var numStr = ('_' + number).replace('_', '');
        var buffer = [];
        for (var i = 0, len = numStr.length; i < len; i += 1) {
            buffer.push(numStr.substring(len - 1 - i, len - i));
            if (((i + 1) % 3 == 0) && (i != len - 1)) {
                buffer.push(sDelimeter);
            }
        }

        return buffer.reverse().join('').replace(",.", ".");
};

I got the code from the following link Link. now when I first navigate to the list view the new Sum column will be shown correctly. but if I click on let say the list view name, then the sum will disappear, but if i do a column based filtering the sum will be updated... and if I want to show the column back I need to do a refresh of the web page.. so can anyone advice on this? I think the problem is related to the fact that doing an Ajax update for the list view will not force the JSLINK to fire.

EDIT Now i editted my JSlink as follow, based on @Dylan reply:-

var _totalValue = 0.0;
var _totalColumn = 27;  // Specify total number of columns in list view.
var _columnIndex = 10;  // Specify the index of the column where you want to display sum values. (i.e. index for first column = 1)

(function myCSRRendering () {

    var calculatedFieldCtx = {};  

    calculatedFieldCtx.Templates = {};

    calculatedFieldCtx.Templates.Fields = {
        "Yearof2016MLC": {
            "View": CalculatedFieldViewTemplate
        }
    };
 SPClientTemplates.TemplateManager.RegisterTemplateOverrides(calculatedFieldCtx); 
    calculatedFieldCtx.OnPostRender = [];
    calculatedFieldCtx.OnPostRender.push(function()
    {  
        // Specify id of the list view table for which you want to display sum values. 
        var HTMLTableElement = document.getElementById("{B3D883A5-6962-47FD-BDEF-BB83FF4C78EA}-{C86BA145-8C22-47E8-938C-11B8C7F855C3}");

                var tbodyElement = document.createElement('thead');
                tbodyElement.id = "customAggWPQ";

                var trElement = document.createElement('tr');

                var tdElement;
                for(var i = 1; i <= _totalColumn; i++) {
                        tdElement = document.createElement('th');
                        tdElement.id = "tdElement" + i;
                        if( i == _columnIndex) {
                              tdElement.innerHTML = "<b>Sum= " + numberFormat(_totalValue) + "</b>";
                        }
                        trElement.appendChild(tdElement);
                }

        tbodyElement.appendChild(trElement);
        if(document.getElementById("customAggWPQ") == null) {
                HTMLTableElement.insertBefore(tbodyElement,HTMLTableElement.firstChild.nextSibling);
        }
        else {
                document.getElementById("tdElement" + _columnIndex).innerHTML = "<b>Sum= " + numberFormat(_totalValue) + "</b>";
        }
        _totalValue = 0.0;
    })

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(
        calculatedFieldCtx
    );

})();


function CalculatedFieldViewTemplate(ctx) {       
    _totalValue += parseFloat((ctx.CurrentItem.Yearof2016MLC).replace(',', ''));

    return ctx.CurrentItem.Yearof2016MLC;
}
// register for MDS enabled sites
RegisterModuleInit('http://servername/offices/Shared%20Documents/sum3.js', myCSRRendering);

// fallback for non-MDS enabled sites
myCSRRendering(); 
var numberFormat = function(number) {
        var sDelimeter = ',';
        number = Math.round(parseFloat(number) * 100) / 100;
        var numStr = ('_' + number).replace('_', '');
        var buffer = [];
        for (var i = 0, len = numStr.length; i < len; i += 1) {
            buffer.push(numStr.substring(len - 1 - i, len - i));
            if (((i + 1) % 3 == 0) && (i != len - 1)) {
                buffer.push(sDelimeter);
            }
        }

        return buffer.reverse().join('').replace(",.", ".");
};

but now the sum field will not be shown neither when the page first load nor when doing a hard refresh for the web browser !!

Was it helpful?

Solution

If MDS is enabled, you may need to take extra steps to ensure that your CSR script is recognized by the MDS system as something that needs to always run.

The MDS system has a function called RegisterModuleInit that has two parameters - a path to a script file, and the name of a function in that file that should always be run.

So in order to get the CSR script working with that, you have to change it from using an IIFE to having a named entry point function. This usually ends up looking something like this:

function myCSRRendering () {
    var myCtx = {};
    myCtx.Templates = {};
    myCtx.Templates.Fields = {
        "MyField": {
            "View": RenderMyField
        }
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(myCtx); 
};

function RenderMyField (ctx) {
    // do whatever you need for rendering in here
    return myOverrideHTML;
}

// register for MDS enabled sites
RegisterModuleInit('/path/to/my/CSR_Script.js', myCSRRendering);

// fallback for non-MDS enabled sites
myCSRRendering();

Here's a good blog post that talks about it in more detail.


To address your code edit - you have added the name of the function, but you still have it as an IIFE, which you need to remove.

What you have:

(function myFunctionName() {
    // you code here
})();

What you need to have:

function myFunctionName() {
    // you code here
};
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top