1

In a document library's /Forms/AllItems.aspx, I am trying to render a column from ID to a file URL (FileLeafRef).

However this line of code:

  clientContext = new SP.ClientContext.get_current();

is giving the error:

Uncaught TypeError: Cannot read property 'get_current' of undefined

I followed this reference in stackexchange to amend my code. The error no longer show up by rending is not triggered. In below code, CSR_Setup is triggered. However overrideNameFieldTemplate and getFileLeafRefbyID is not triggered at all. The Allitems.aspx shows up without error and no change.

What's wrong?

(function () {

ExecuteOrDelayUntilScriptLoaded(CSR_Setup, "SP.js");
function CSR_Setup(){ 
    var overrideNameField = {}; 
    overrideNameField.Templates = {}; 
    overrideNameField.Templates.Fields = {
        "InstructionLibID": { "View": overrideNameFieldTemplate } 
    }; 
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideNameField); 
}

function overrideNameFieldTemplate(ctx) { 
    var InstructionLibID = ctx.CurrentItem.InstructionLibID;
    var fileRef = getFileLeafRefbyID("Instruction",InstructionLibID);
    if (InstructionLibID) {
        return "<a href='"+ fileRef + "'>Download</a>"; 
    }
    else {
        return "N/A"; 
    }
}

function getFileLeafRefbyID(LibName,Id){        
        clientContext = new SP.ClientContext.get_current();
      oWebsite = clientContext.get_web();
      oList = oWebsite.get_lists().getByTitle(LibName);

        this.oListItem = oList.getItemById(Id);
        clientContext.load(this.oListItem);
        clientContext.executeQueryAsync(
        Function.createDelegate(this, successHandler),
        Function.createDelegate(this, errorHandler)
    );

        function successHandler() {
            return(oListItem.get_item('FileLeafRef'));
        }

        function errorHandler() {
            console.log('Fail');
        }
}
})();
7
  • Are you sure InstructionLibID is the internal name of your lookup column?
    – Submits
    May 27 '16 at 10:33
  • Yes. If I remove the line calling "getFileLeafRefbyID". The InstructionLibID column will be rendered correctly.
    – Mark L
    May 27 '16 at 10:45
  • Yes. If I remove the line calling "getFileLeafRefbyID" and call Setup_CSR without ExecuteOrDelayUntilScriptLoaded, the InstructionLibID column will be rendered correctly. Hence I am thinking ExecuteOrDelayUntilScriptLoaded actually delay my code to AFTER everything render complete?
    – Mark L
    May 27 '16 at 10:52
  • You have a ton on undeclared variables in getFileLeafRefByID and also you do not have to do new on SP.ClientContext.get_current();. But none of those things should throw "Uncaught TypeError: Cannot read property 'get_current' of undefined" May 27 '16 at 10:53
  • Which variables have problem? Because it doesn't return any error so I may not aware.
    – Mark L
    May 27 '16 at 10:59
1

Encapsulate the content of getFileLeafRefId function in

 SP.SOD.executeFunc("sp.js", "SP.ClientContext", function () {YOUR CODE HERE }

I usually wait for "clienttemplates.js" to load for executing my jslink overrides like:

SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () { OVERRIDE CODE HERE } 

UPDATE: Please see below your code changed with the changes I suggested (haven't tested it my self). Give it a try.

(function () {
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () {

    var overrideNameField = {}; 
    overrideNameField.Templates = {}; 
    overrideNameField.Templates.Fields = {
        "InstructionLibID": { "View": overrideNameFieldTemplate } 
    }; 
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideNameField); 


    function overrideNameFieldTemplate(ctx) { 
        var InstructionLibID = ctx.CurrentItem.InstructionLibID;
        var fileRef = getFileLeafRefbyID("Instruction",InstructionLibID);
        if (InstructionLibID) {
            return "<a href='"+ fileRef + "'>Download</a>"; 
        }
        else {
            return "N/A"; 
        }
    }

    function getFileLeafRefbyID(LibName,Id){     
        SP.SOD.executeFunc("sp.js", "SP.ClientContext", function () {   
            var clientContext = new SP.ClientContext.get_current();
            var oWebsite = clientContext.get_web();
            var oList = oWebsite.get_lists().getByTitle(LibName);

            this.oListItem = oList.getItemById(Id);
            clientContext.load(this.oListItem);
            clientContext.executeQueryAsync(
                Function.createDelegate(this, successHandler),
                Function.createDelegate(this, errorHandler));

            function successHandler() {
                return(oListItem.get_item('FileLeafRef'));
            }

            function errorHandler() {
                console.log('Fail');
            }
        });
    }
}); 
})();
1
  • Should I placed this code in JSLink or insert in a Content Editor webpart?
    – Mark L
    May 31 '16 at 2:49
2

If you really want to use ClientContext with CSR Templating, you have do delay Form-Rendering until everything is loaded. You can achieve this by overloading some objects in ClientFormManager:

(function () {

    interceptForm();

    //... continue with "normal" CSR templating...


})();

function interceptForm()
{
    var CSIntercept = SPClientForms.ClientFormManager.GetClientForm;

    SPClientForms.ClientFormManager.GetClientForm = function (frmName) {
        frm = CSIntercept(frmName);
        frm.RenderClientFormCS = frm.RenderClientForm;
        frm.RenderClientForm = function () {
            ExecuteOrDelayUntilScriptLoaded(function () {
                frm.RenderClientFormCS();
            }, 'sp.js');
        }
        return frm;
    };
}
1
  • Wow, this seems like an excellent solution, nicely done. Aside from the obvious time that any async calls made using the client context would add, does just waiting for sp.js to load add any noticeable delay in the page loading and rendering? Oct 20 '16 at 14:16
0

Replace

ExecuteOrDelayUntilScriptLoaded(CSR_Setup, "SP.js");

with

SP.SOD.executeFunc('sp.js', 'SP.ClientContext', CSR_Setup);

1
  • In my test, both statement exactly return same result, CSR_Setup is triggered but no Template Overrides occur.
    – Mark L
    May 27 '16 at 10:57

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.