0

I am unable to make the fields readonly in EditForm.aspx on the basis of logged in User. The ctx.CurrentFieldSchema.FieldType throws an error "Cannot read property 'FieldType' of null" Below is the code

(function () { 

    // Create object that have the context information about the field that we want to change it's output render  
    var readonlyFiledContext = {}; 
    readonlyFiledContext.Templates = {}; 
    readonlyFiledContext.Templates.Fields = { 
        // Apply the new rendering for Age field on Edit forms 
        "Test": { 
            "EditForm": readonlyFieldTemplate 
        } 

    }; 

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(readonlyFiledContext); 

})(); 


var allGroups;
// This function provides the rendering logic 
function readonlyFieldTemplate(ctx) { 
  SP.SOD.executeOrDelayUntilScriptLoaded(function(){
      var currentContext = SP.ClientContext.get_current();
    var currentWeb = currentContext.get_web();
    var currentUser = currentContext.get_web().get_currentUser();
    currentContext.load(currentUser);
    allGroups = currentUser.get_groups();
    currentContext.load(allGroups);
    currentContext.executeQueryAsync(function(){
         var groupsEnum = allGroups.getEnumerator();
    while (groupsEnum.moveNext()) {
        var item = groupsEnum.get_current();
        groupName = item.get_title();
        if (groupName.includes("Site Member")) {
            isUserGroupMember=true;
            break;
    }
    }
        if(isUserGroupMember){
        switch (ctx.CurrentFieldSchema.FieldType) { 
        case "Text": 
        case "Number": 
        case "Integer": 
        case "Currency": 
        case "Choice": 
        case "Computed": 
            return SPFieldText_Edit(ctx); 

        case "Boolean": 
            return SPFieldBoolean_Edit(ctx); 


        case "DateTime": 
            return SPFieldDateTime_Edit(ctx); 

    }   
        }
        else{
            switch (ctx.CurrentFieldSchema.FieldType) { 
        case "Text": 
        case "Number": 
        case "Integer": 
        case "Currency": 
        case "Choice": 
        case "Computed": 
            return SPField_FormDisplay_Default(ctx); 

        case "Boolean": 
            return SPField_FormDisplay_DefaultNoEncode(ctx); 


        case "DateTime": 
            return SPFieldDateTime_Display(ctx); 

    } 
        }

    }, OnFailure);

  }, 'sp.js');
    //Reuse ready sharepoint javascript libraries 

} 




function OnFailure(sender, args) {
    // log an error?
    // no need to do anything with the field because it is already hidden
}
0

Don't know if you found a solution to this yet, but that is probably happening because executeOrDelayUntilScriptLoaded probably does not stop the rendering process, so by the time you've waited for sp.js to load and made your query for the groups, ctx.CurrentItem is long gone.

Making async calls using the JSOM within the rendering cycle is tricky, because normally the rendering happens early on, and is finished by the time sp.js is loaded and SP.ClientContext is available.

Another user posted a very interesting answer here that shows a technique you can use to hijack / intercept the normal rendering cycle and delay it until the client context is available. Then you can make your async calls from within your rendering override code the way you want to.

Maybe you can use something like this to get what you want?

Code example is as follows (not written or tested by me, just copied from the other answer):

(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;
    };
}

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.