0

exceute SPClientTemplates.TemplateManager.RegisterTemplateOverrides from Context.executeQueryAsync Success

Below is my code

(function () { 
    var isCurrentUserInGroup;
    var flag=false;
    var hiddenFiledContext = {}; 
    SP.SOD.executeOrDelayUntilScriptLoaded(IsCurrentUserMemberOfGroup, 'sp.js');    
    function IsCurrentUserMemberOfGroup() {           
        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(OnSuccess,OnFailure);
    }

    function OnSuccess(sender, args) {
         isCurrentUserInGroup = false;          
         var groupsEnum = allGroups.getEnumerator();
         while (groupsEnum.moveNext()) {
             var item = groupsEnum.get_current();
             groupName = item.get_title();
             if (groupName.includes("Site Members")) {
                 isCurrentUserInGroup = true;               
                 break;
             }
         }
         SP.SOD.executeOrDelayUntilScriptLoaded(CSR_Setup, 'sp.js');

    }

    function OnFailure(sender, args) {
       isCurrentUserInGroup=false;

    } 

    (window.jQuery || document.write('<script src="/sites/dev-akansha/SiteAssets/jquery-3.1.1.js"></script>'));  

    // Create object that have the context information about the field that we want to change it's output render  
    function CSR_Setup(){

        hiddenFiledContext.Templates = {};  
        hiddenFiledContext.Templates.OnPostRender = hiddenFiledOnPreRender; 
        alert(isCurrentUserInGroup);
        if(isCurrentUserInGroup){
            hiddenFiledContext.Templates.Fields = { 
                // Apply the new rendering for Age field on New and Edit forms 
                "Test1": { 

                    "EditForm": hiddenFiledTemplate 
                } 

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

})(); 


// This function provides the rendering logic 
function hiddenFiledTemplate() { 
    return "<span class='csrHiddenField'></span>"; 
} 

// This function provides the rendering logic 
function hiddenFiledOnPreRender(ctx) { 
    jQuery(".csrHiddenField").closest("tr").hide(); 
} 
1

One of the things you have to understand is that page rendering happens very early in the life of the page, and by the time sp.js is loaded, the rendering cycle is over and done with. So you really can't wait until sp.js is loaded before calling your CSR_Setup function.

When I want to hide fields based on group membership, I take kind of an opposite approach, because waiting for an async call to execute and then determining if I should hide the field or not would possibly result in the field being visible for a brief moment and then disappearing. So I usually try to hide the field as soon as possible (for everyone), then make the async call to check group membership, and then if the user is a member of the correct group, show the already hidden field.

Restructuring your code to achieve that would look something like this:

// ensure jquery is loaded
(window.jQuery || document.write('<script src="/sites/dev-akansha/SiteAssets/jquery-3.1.1.js"></script>'));

// register your override and set up your field to be hidden 
(function () {
    hiddenFiledContext.Templates = {};
    hiddenFiledContext.Templates.Fields = {
        // Apply the new rendering for Age field on New and Edit forms 
        "Test1": {
            "EditForm": hiddenFiledTemplate
        }
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(hiddenFiledContext);
})();

function hiddenFiledTemplate() {
    return "<span class='csrHiddenField'></span>";
}

// after the rendering runs, your span is there and ready to be found.
// _spBodyOnLoad functions run after the DOM is loaded, so the page
// will have been rendered by the time the next function is called
_spBodyOnLoadFunctionNames.push('HideMyField');

function HideMyField() {
    jQuery(".csrHiddenField").closest("tr").hide();
    // then set up the async call
    SP.SOD.executeOrDelayUntilScriptLoaded(IsCurrentUserMemberOfGroup, 'sp.js');
}

// declare this outside the scope of the async call function 
// so it is available in the success callback
var allGroups;

function IsCurrentUserMemberOfGroup() {
    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(OnSuccess, OnFailure);
}

function OnSuccess(sender, args) {
    var groupsEnum = allGroups.getEnumerator();
    while (groupsEnum.moveNext()) {
        var item = groupsEnum.get_current();
        groupName = item.get_title();
        if (groupName.includes("Site Members")) {
            ShowMyField();
            break;
        }
    }
}

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

function ShowMyField() {
    jQuery(".csrHiddenField").closest("tr").show();
}

The part of that I am unsure about is the dynamic loading of jQuery. I do not usually use that technique so I am not sure if the syntax is correct for that line of code. But in a more general sense, that is how I would go about structuring my code to hide a field based on group membership when using an async call to check the membership.

  • Thank u :) It worked! – Akansha Madhvi Oct 9 '16 at 4:11
  • Hi Dylan. I want to make the fields readonly on the basis of the logged in user. – Akansha Madhvi Oct 19 '16 at 9:36

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.