7

I have been working on a CSR script for the New / Edit / Display forms of a list.

I am attempting to use OnPostRender to perform an action after all fields on the form have been rendered (hide a particular tr).

At the moment my testing is showing OnPostRender firing once per field and before the 3 'InitCallback' (one for each customized field) events fire.

Even with the simplest example I can find, OnPostRender seems to fire for each field.

function $_global_kgjslinkcontactsnew_test() {    

SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
    OnPreRender: function () { console.log('CSR OnPreRender'); },
    OnPostRender: function () { console.log('CSR OnPostRender'); }        
});

} $_global_kgjslinkcontactsnew_test();

My full script is posted below but I think this must be behavior by design.

How do you apply CSR code once after the form is rendered ???

I have a function to return the default SharePoint HTML for my fields and another that I am using in the OnPostRender to hide a particular tr in the DOM but even with those commented out I am getting the same effect.

Is there an error in my script or is OnPostRender supposed to fire once per field ? If it is, how can I run my function once after all fields have rendered ?

function $_global_kgjslinkcontactsnew_test() {

Type.registerNamespace('KG');

KG.jslink_contactsnew = KG.jslink_contactsnew || {};
KG.jslink_contactsnew.Templates = KG.jslink_contactsnew.Templates || {};
KG.jslink_contactsnew.Functions = KG.jslink_contactsnew.Functions || {};

KG.jslink_contactsnew.Functions.test = function (ctx) {

    var html = KG.jslink_contactsnew.Functions.getDefaultFieldHtml(ctx, ctx.CurrentFieldSchema, ctx.CurrentItem, ctx.ListSchema);

    var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);
    var fieldInternalName = ctx.CurrentFieldSchema.Name;

    var contactTypeName = "KGContactType";
    var contactTypeField = window[ctx.FormUniqueId + "FormCtx"].ListSchema[contactTypeName];
    var contactTypeControlId = contactTypeField.Name + "_" + contactTypeField.Id + "_$DropDown" + contactTypeField.FieldType + "Field";
    var contactTypeValue = window[ctx.FormUniqueId + "FormCtx"].ListData["KGContactType"];

    //Register GetValueCallback function for current field for when save is clicked.
    formCtx.registerGetValueCallback(formCtx.fieldName, function () {
        return document.getElementById(formCtx.fieldSchema.Id).value;
    });

    //Register InitCallBack function for current field for when it changes.
    formCtx.registerInitCallback(formCtx.fieldName, function () {

        console.log("init function ran for " + formCtx.fieldName);

    });

    return html;
}

KG.jslink_contactsnew.Functions.testOnPostRender = function (ctx) {

    console.log("OnPostRender");

    var contactTypeName = "KGContactType";
    var contactTypeField = window[ctx.FormUniqueId + "FormCtx"].ListSchema[contactTypeName];
    var contactTypeControlId = contactTypeField.Name + "_" + contactTypeField.Id + "_$DropDown" + contactTypeField.FieldType + "Field";
    var contactTypeValue = window[ctx.FormUniqueId + "FormCtx"].ListData["KGContactType"];

    var firstNameName = "FirstName";
    var firstNameField = window[ctx.FormUniqueId + "FormCtx"].ListSchema[firstNameName];
    var firstNameControlId = firstNameField.Name + "_" + firstNameField.Id + "_$" + firstNameField.FieldType + "Field";  
    var firstNameControl = document.getElementById(firstNameControlId);
    var el;

    if (contactTypeValue == "Organization") {
        el = KG.jslink_contactsnew.Functions.upTo(firstNameControl, "tr");
        el.style.display = "";
    }
    else {
        el = KG.jslink_contactsnew.Functions.upTo(firstNameControl, "tr");
        el.style.display = "none";
    }

    // Find first ancestor of el with tagName
    // or undefined if not found
}

KG.jslink_contactsnew.Functions.upTo = function (el, tagName) {

    tagName = tagName.toLowerCase();

    while (el && el.parentNode) {
        el = el.parentNode;
        if (el.tagName && el.tagName.toLowerCase() == tagName) {
            console.log("found " + el.tagName);
            return el;
        }
        else { console.log(el.tagName); }
    }

    // Many DOM methods return null if they don't 
    // find the element they are searching for
    // It would be OK to omit the following and just
    // return undefined
    return null;
}

KG.jslink_contactsnew.Functions.getDefaultFieldHtml = function (renderCtx, field, listItem, listSchema) {

    // Get field type and whether we are in DISPLAY , NEW, EDIT or VIEW mode.
    var fieldType = renderCtx.CurrentFieldSchema.FieldType;
    var controlMode = renderCtx.ControlMode;

    // DISPLAY FORM default field rendering.
    if (controlMode == 1) {
        switch (renderCtx.CurrentFieldSchema.FieldType) {

            case 'Text':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Number':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Integer':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Boolean':
                return SPField_FormDisplay_DefaultNoEncode(renderCtx);
            case 'Note':
                return SPFieldNote_Display(renderCtx);
            case 'Currency':
                return SPField_FormDisplay_Default(renderCtx);
            case 'File':
                return SPFieldFile_Display(renderCtx);
            case 'Calculated':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Choice':
                return SPField_FormDisplay_Default(renderCtx);
            case 'MultiChoice':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Lookup':
                return SPFieldLookup_Display(renderCtx);
            case 'LookupMulti':
                return SPFieldLookup_Display(renderCtx);
            case 'Computed':
                return SPField_FormDisplay_Default(renderCtx);
            case 'URL':
                return SPFieldUrl_Display(renderCtx);
            case 'User':
                return SPFieldUser_Display(renderCtx);
            case 'UserMulti':
                return SPFieldUserMulti_Display(renderCtx);
            case 'DateTime':
                return SPFieldDateTime_Display(renderCtx);
            case 'Attachments':
                return SPFieldAttachments_Display(renderCtx);
            default:
                console.log("Fieldtype " + fieldType + "not found");
                return "";
        }
    }

    // NEW and EDIT FORM default field rendering.
    if (controlMode == 2 || controlMode == 3) {
        switch (renderCtx.CurrentFieldSchema.FieldType) {

            case 'Text':
                return SPFieldText_Edit(renderCtx);
            case 'Number':
                return SPFieldNumber_Edit(renderCtx);
            case 'Integer':
                return SPFieldNumber_Edit(renderCtx);
            case 'Boolean':
                return SPFieldBoolean_Edit(renderCtx);
            case 'Note':
                return SPFieldNote_Edit(renderCtx);
            case 'Currency':
                return SPFieldNumber_Edit(renderCtx);
            case 'File':
                return SPFieldFile_Edit(renderCtx);
            case 'Calculated':
                return SPField_FormDisplay_Empty(renderCtx);
            case 'Choice':
                return SPFieldChoice_Edit(renderCtx);
            case 'MultiChoice':
                return SPFieldMultiChoice_Edit(renderCtx);
            case 'Lookup':
                return SPFieldLookup_Edit(renderCtx);
            case 'LookupMulti':
                return SPFieldLookup_Edit(renderCtx);
            case 'Computed':
                return SPField_FormDisplay_Default(renderCtx);
            case 'URL':
                return SPFieldUrl_Edit(renderCtx);
            case 'User':
                return SPClientPeoplePickerCSRTemplate(renderCtx);
            case 'UserMulti':
                return SPClientPeoplePickerCSRTemplate(renderCtx);
            case 'DateTime':
                return SPFieldDateTime_Edit(renderCtx);
            case 'Attachments':
                return SPFieldAttachments_Default(renderCtx);
            default:
                console.log("Fieldtype " + fieldType + "not found");
                return "";
        }
    }

    // VIEW default field rendering.
    if (controlMode == 4) {

        //Copy Paste of Jim Browns awesome helper function to return default View CSR field rendering

        var renderingTemplateToUse = null;

        var fieldRenderMap = {
            Computed: new ComputedFieldRenderer(field.Name),
            Attachments: new AttachmentFieldRenderer(field.Name),
            User: new UserFieldRenderer(field.Name),
            UserMulti: new UserFieldRenderer(field.Name),
            URL: new UrlFieldRenderer(field.Name),
            Note: new NoteFieldRenderer(field.Name),
            Recurrence: new RecurrenceFieldRenderer(field.Name),
            CrossProjectLink: new ProjectLinkFieldRenderer(field.Name),
            AllDayEvent: new AllDayEventFieldRenderer(field.Name),
            Number: new NumberFieldRenderer(field.Name),
            BusinessData: new BusinessDataFieldRenderer(field.Name),
            Currency: new NumberFieldRenderer(field.Name),
            DateTime: new DateTimeFieldRenderer(field.Name),
            Text: new TextFieldRenderer(field.Name),
            Lookup: new LookupFieldRenderer(field.Name),
            LookupMulti: new LookupFieldRenderer(field.Name),
            WorkflowStatus: new RawFieldRenderer(field.Name)
        };

        if (field.XSLRender == '1') {

            renderingTemplateToUse = new RawFieldRenderer(field.Name);
        }
        else {

            renderingTemplateToUse = fieldRenderMap[field.FieldType];
            if (renderingTemplateToUse == null)
                renderingTemplateToUse = fieldRenderMap[field.Type];
        }

        if (renderingTemplateToUse == null)
            renderingTemplateToUse = new FieldRenderer(field.Name);

        return renderingTemplateToUse.RenderField(renderCtx, field, listItem, listSchema);
    }

    //No match found for default render.
    console.log("CSR Default Field Render Failed...");
    return "Default Field Render Failed";
}

KG.jslink_contactsnew.Templates.Fields = {
    //'Title': {
    //  'View': function () { return null; }
    //},
    'KGContactType': {
        'EditForm': KG.jslink_contactsnew.Functions.test,
        'NewForm': KG.jslink_contactsnew.Functions.test
    },
    'FullName': {
        'EditForm': KG.jslink_contactsnew.Functions.test,
        'NewForm': KG.jslink_contactsnew.Functions.test
    },
    'Company': {
        'EditForm': KG.jslink_contactsnew.Functions.test,
        'NewForm': KG.jslink_contactsnew.Functions.test
    }
}

KG.jslink_contactsnew.Templates.OnPostRender = KG.jslink_contactsnew.Functions.testOnPostRender;

//KG.jslink_contactsnew.BaseViewID = 1;

KG.jslink_contactsnew.ListTemplateType = 105;   

//Make the magic happen....
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(KG.jslink_contactsnew);

} $_global_kgjslinkcontactsnew_test();
  • What did you set the Target Control Type as for your template? I believe if you set it to "Field", OnPreRender and OnPostRender will fire once per field (since that's the scope you set), but if you set the Target Control Type to "View", they will fire only once per entire view rendering. I have tested that with View, and I had it work as expected. I do not know the behavior is if you set the Target Control Type to "Form". – Dylan Cristy Apr 17 '15 at 21:40
  • As best I can find, Target Control Type is set only when publishing a template into the masterpage gallery. I have not done this yet and assume I will use this when creating display templates for search etc ? eliostruyf.com/… The link above seems to suggest that the property defines which display templates can be used where, presumably when accessed from the MPG ? I use code to set the jslink on my forms (sharepoint.stackexchange.com/questions/77976/…). – Satyrical Apr 17 '15 at 22:36
  • 1
    Right, but are your JS files for your templates stored within the site somewhere, or on the file system in the _layouts directory? If they are on the site somewhere, you can just add the JavaScript Display Template content type to whatever library it is, and then set those files to be that content type, and then you will be able to set the Target Control Type for those files. I don't think it matters how you are actually setting the jslink on the forms. – Dylan Cristy Apr 23 '15 at 16:06
  • Thanks, great tip ! At the moment I am just deploying to _layouts. Now that you have mentioned the JavaScript Display Template content type I can see how that might be useful. In the near future I will be working on my search templates at which point I will delve into this side of it in depth. Current piece was part of creating a custom team site web template. When I start poking around in MPG I will test and see if it changes onpostrender behaviour as you have suggested it might. – Satyrical Apr 23 '15 at 18:14
10

So it seems that the order is :

onPreRender
field1 override function --> (set registerInitCallback, return html etc.)
onPostRender

onPreRender
field2 override function --> (set registerInitCallback, return html etc.)
onPostRender

onPreRender
field3 (non override field, standard SharePoint render)
onPostRender
... > so on for all form fields.

field1 registerInitCallback function
field2 registerInitCallback function

In the end I used registerInitCallback as I could guarantee all fields had been rendered on the form and then inside this callback I wired up 'onchange' events to the relevant fields.

My full script is listed below in case it is useful for someone. It includes a helper function to return the default html for any field type.

The script hides or shows some form rows based on changing a choice field.

function $_global_kgjslinkcontactsnew_test() {

Type.registerNamespace('KG');

KG.jslink_contactsnew = KG.jslink_contactsnew || {};
KG.jslink_contactsnew.Templates = KG.jslink_contactsnew.Templates || {};
KG.jslink_contactsnew.Functions = KG.jslink_contactsnew.Functions || {};

//This script is deployed to layouts as kgjslinkcontactsnew_test.js.
//The jslink property for new, edit and display forms is set to clienttemplates.js|kgjslinkcontactsnew.js.
//The script is for the forms of a standard contacts list with a custom choice field called KGContactType.
//When KGContactType is set to Organization, the firstname, lastname and fullname fields are hidden and company name is highlighted.
//When KGContactType is set to Organization, and company is edited, the value is copied to the lastname and fullname fields.

//Note: onPostRender fires after each individual field html has been returned for EVERY field (even ones not overridden).
// registerInitCallback fires once for each field that has been overridden AFTER all fields have been rendered.  This is why I am using 
// registerInitCallback to set the field logic because I need other fields to already exist on the form.

KG.jslink_contactsnew.Functions.overrideFields = function (ctx) {

    //Get the default SharePoint html for the field using handy helper function.
    var html = KG.jslink_contactsnew.Functions.getDefaultFieldHtml(ctx, ctx.CurrentFieldSchema, ctx.CurrentItem, ctx.ListSchema);

    var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);
    var fieldInternalName = ctx.CurrentFieldSchema.Name;

    //Initial value of my choice field.
    var InitialcontactTypeValue = window[ctx.FormUniqueId + "FormCtx"].ListData["KGContactType"];

    //Variables for all of the form fields that I need to get values from or set values in.
    var contactTypeField = window[ctx.FormUniqueId + "FormCtx"].ListSchema["KGContactType"];
    var contactTypeControlId = contactTypeField.Name + "_" + contactTypeField.Id + "_$DropDown" + contactTypeField.FieldType;        
    var firstNameField = window[ctx.FormUniqueId + "FormCtx"].ListSchema["FirstName"];
    var firstNameControlId = firstNameField.Name + "_" + firstNameField.Id + "_$" + firstNameField.FieldType + "Field";
    var lastNameField = window[ctx.FormUniqueId + "FormCtx"].ListSchema["Title"];
    var lastNameControlId = lastNameField.Name + "_" + lastNameField.Id + "_$" + lastNameField.FieldType + "Field";
    var fullNameField = window[ctx.FormUniqueId + "FormCtx"].ListSchema["FullName"];
    var fullNameControlId = fullNameField.Name + "_" + fullNameField.Id + "_$" + fullNameField.FieldType + "Field";
    var companyField = window[ctx.FormUniqueId + "FormCtx"].ListSchema["Company"];
    var companyControlId = companyField.Name + "_" + companyField.Id + "_$" + companyField.FieldType + "Field";        

    if (fieldInternalName == "KGContactType") {            
        formCtx.registerInitCallback(fieldInternalName, function () {

            // 1 - Add an onchange handler so that we can manipulate the dom when this control is changed.
            $addHandler($get(contactTypeControlId), "change", function (e) {                   

                var fieldControl = $get(contactTypeControlId);
                var newValue = fieldControl.value;

                var firstNameControl = $get(firstNameControlId);
                var lastNameControl = $get(lastNameControlId);
                var fullNameControl = $get(fullNameControlId);
                var companyControl = $get(companyControlId);                  

                if (newValue == "Organization") {
                    KG.jslink_contactsnew.Functions.upTo(firstNameControl, "tr").style.display = "none";
                    KG.jslink_contactsnew.Functions.upTo(lastNameControl, "tr").style.display = "none";
                    KG.jslink_contactsnew.Functions.upTo(fullNameControl, "tr").style.display = "none";
                    KG.jslink_contactsnew.Functions.upTo(companyControl, "tr").style.backgroundColor = "#ada";                            
                }
                else {                        
                    KG.jslink_contactsnew.Functions.upTo(firstNameControl, "tr").style.display = "";
                    KG.jslink_contactsnew.Functions.upTo(lastNameControl, "tr").style.display = "";
                    KG.jslink_contactsnew.Functions.upTo(fullNameControl, "tr").style.display = "";
                    KG.jslink_contactsnew.Functions.upTo(companyControl, "tr").style.removeProperty("background-color");
                    KG.jslink_contactsnew.Functions.upTo(lastNameControl, "tr").style.backgroundColor = "#ada";
                }                    
            });
            // 2 - Make sure the controls value is displayed on the form.
            ctx.FormContext.updateControlValue(fieldInternalName, $get(contactTypeControlId).value);

            // 3 - Set initial state of other fields based on this one.
            // (remember because this is in registerInitCallback it will occur once 
            // AFTER all fields are rendered on the form).
            var firstNameControl = $get(firstNameControlId);
            var lastNameControl = $get(lastNameControlId);
            var fullNameControl = $get(fullNameControlId);
            var companyControl = $get(companyControlId);

            if (InitialcontactTypeValue == "Organization") {
                KG.jslink_contactsnew.Functions.upTo(firstNameControl, "tr").style.display = "none";
                KG.jslink_contactsnew.Functions.upTo(lastNameControl, "tr").style.display = "none";
                KG.jslink_contactsnew.Functions.upTo(fullNameControl, "tr").style.display = "none";
                KG.jslink_contactsnew.Functions.upTo(companyControl, "tr").style.backgroundColor = "#ada";
            }
            else {
                KG.jslink_contactsnew.Functions.upTo(firstNameControl, "tr").style.display = "";
                KG.jslink_contactsnew.Functions.upTo(lastNameControl, "tr").style.display = "";
                KG.jslink_contactsnew.Functions.upTo(fullNameControl, "tr").style.display = "";
                KG.jslink_contactsnew.Functions.upTo(companyControl, "tr").style.removeProperty("background-color");
                KG.jslink_contactsnew.Functions.upTo(lastNameControl, "tr").style.backgroundColor = "#ada";
            }
        });

        //Register GetValueCallback function for current field for when save is clicked.
        formCtx.registerGetValueCallback(formCtx.fieldName, function () {
            return document.getElementById(contactTypeControlId).value;
        });           
    }

    if (fieldInternalName == "Company") {
        formCtx.registerInitCallback(fieldInternalName, function () {

            //Add an onchange handler so that we can manipulate the dom when this control is changed.
            $addHandler($get(companyControlId), "change", function (e) {

                var fieldControl = $get(companyControlId);
                var newValue = fieldControl.value;

                var contactTypeControl = $get(contactTypeControlId);
                var firstNameControl = $get(firstNameControlId);
                var lastNameControl = $get(lastNameControlId);
                var fullNameControl = $get(fullNameControlId);                    

                if (contactTypeControl.value == "Organization") {
                    lastNameControl.value = newValue;
                    fullNameControl.value = newValue;
                    firstNameControl.value = "";
                }
            });
            //Make sure the controls value is displayed on the form.
            ctx.FormContext.updateControlValue(fieldInternalName, $get(companyControlId).value);
        });

        //Register GetValueCallback function for current field for when save is clicked.
        formCtx.registerGetValueCallback(formCtx.fieldName, function () {
            return document.getElementById(companyControlId).value;
        });
    }

    if (fieldInternalName == "FirstName") {
        formCtx.registerInitCallback(fieldInternalName, function () {

            //Add an onchange handler so that we can manipulate the dom when this control is changed.
            $addHandler($get(firstNameControlId), "change", function (e) {

                var fieldControl = $get(firstNameControlId);
                var newValue = fieldControl.value;

                var contactTypeControl = $get(contactTypeControlId);
                var lastNameControl = $get(lastNameControlId);
                var fullNameControl = $get(fullNameControlId);

                if (contactTypeControl.value == "Organization") {

                    fieldControl.value = "";                                                
                }
                else
                {
                    fullNameControl.value = newValue + " " + lastNameControl.value;
                }                   
            });
            //Make sure the controls value is displayed on the form.
            ctx.FormContext.updateControlValue(fieldInternalName, $get(firstNameControlId).value);
        });

        //Register GetValueCallback function for current field for when save is clicked.
        formCtx.registerGetValueCallback(formCtx.fieldName, function () {
            var contactTypeControl = $get(contactTypeControlId);

            if (contactTypeControl.value == "Organization") { return ""; }
            else { return document.getElementById(firstNameControlId).value; }                
        });
    }

    //Set initial state based on this field.
    if (fieldInternalName == "Title") {
        formCtx.registerInitCallback(fieldInternalName, function () {

            //Add an onchange handler so that we can manipulate the dom when this control is changed.
            $addHandler($get(lastNameControlId), "change", function (e) {

                var fieldControl = $get(lastNameControlId);
                var newValue = fieldControl.value;

                var contactTypeControl = $get(contactTypeControlId);
                var firstNameControl = $get(firstNameControlId);                    
                var fullNameControl = $get(fullNameControlId);
                var companyControl = $get(companyControlId);

                if (contactTypeControl.value == "Organization") {

                    fieldControl.value = companyControl.value;
                }
                else {
                    fullNameControl.value = firstNameControl.value + " " + newValue;
                }                    
            });
            //Make sure the controls value is displayed on the form.
            ctx.FormContext.updateControlValue(fieldInternalName, $get(lastNameControlId).value);
        });

        //Register GetValueCallback function for current field for when save is clicked.
        formCtx.registerGetValueCallback(formCtx.fieldName, function () {
            var contactTypeControl = $get(contactTypeControlId);
            var companyControl = $get(companyControlId);

            if (contactTypeControl.value == "Organization") { return companyControl.value; }
            else { return document.getElementById(lastNameControlId).value; }
        });
    }

    if (fieldInternalName == "FullName") {
        formCtx.registerInitCallback(fieldInternalName, function () {

            //Add an onchange handler so that we can manipulate the dom when this control is changed.
            $addHandler($get(fullNameControlId), "change", function (e) {

                var fieldControl = $get(fullNameControlId);
                var newValue = fieldControl.value;

                var contactTypeControl = $get(contactTypeControlId);
                var firstNameControl = $get(firstNameControlId);
                var lastNameControl = $get(lastNameControlId);                    
                var companyControl = $get(companyControlId);

                if (contactTypeControl.value == "Organization") {

                    fieldControl.value = companyControl.value;
                }
                else {
                    fieldControl.value = firstNameControl.value + " " + lastNameControl.value;
                }
            });
            //Make sure the controls value is displayed on the form.
            ctx.FormContext.updateControlValue(fieldInternalName, $get(lastNameControlId).value);
        });

        //Register GetValueCallback function for current field for when save is clicked.
        formCtx.registerGetValueCallback(formCtx.fieldName, function () {
            var contactTypeControl = $get(contactTypeControlId);
            var companyControl = $get(companyControlId);
            var firstNameControl = $get(firstNameControlId);
            var lastNameControl = $get(lastNameControlId);

            if (contactTypeControl.value == "Organization") { return companyControl.value; }
            else { return firstNameControl.value + " " + lastNameControl.value; }
        });
    }             

    //Returns default html for field.  We could have manipulated this first if we needed to.
    return html;
}

//Helper function to walk up the dom looking for the closest instance of an element.
//In this case we use it to backtrack to the closest parent tr so we can hide the whole
//field row
KG.jslink_contactsnew.Functions.upTo = function (el, tagName) {

    tagName = tagName.toLowerCase();

    while (el && el.parentNode) {
        el = el.parentNode;
        if (el.tagName && el.tagName.toLowerCase() == tagName) {
            console.log("found " + el.tagName);
            return el;
        }
        else { console.log(el.tagName); }
    }

    // Many DOM methods return null if they don't 
    // find the element they are searching for
    // It would be OK to omit the following and just
    // return undefined
    return null;
}

//Helper function to return the default HTML that SharePoint would render before our CSR override.
KG.jslink_contactsnew.Functions.getDefaultFieldHtml = function (renderCtx, field, listItem, listSchema) {

    // Get field type and whether we are in DISPLAY , NEW, EDIT or VIEW mode.
    var fieldType = renderCtx.CurrentFieldSchema.FieldType;
    var controlMode = renderCtx.ControlMode;

    // DISPLAY FORM default field rendering.
    if (controlMode == 1) {
        switch (renderCtx.CurrentFieldSchema.FieldType) {

            case 'Text':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Number':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Integer':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Boolean':
                return SPField_FormDisplay_DefaultNoEncode(renderCtx);
            case 'Note':
                return SPFieldNote_Display(renderCtx);
            case 'Currency':
                return SPField_FormDisplay_Default(renderCtx);
            case 'File':
                return SPFieldFile_Display(renderCtx);
            case 'Calculated':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Choice':
                return SPField_FormDisplay_Default(renderCtx);
            case 'MultiChoice':
                return SPField_FormDisplay_Default(renderCtx);
            case 'Lookup':
                return SPFieldLookup_Display(renderCtx);
            case 'LookupMulti':
                return SPFieldLookup_Display(renderCtx);
            case 'Computed':
                return SPField_FormDisplay_Default(renderCtx);
            case 'URL':
                return SPFieldUrl_Display(renderCtx);
            case 'User':
                return SPFieldUser_Display(renderCtx);
            case 'UserMulti':
                return SPFieldUserMulti_Display(renderCtx);
            case 'DateTime':
                return SPFieldDateTime_Display(renderCtx);
            case 'Attachments':
                return SPFieldAttachments_Display(renderCtx);
            default:
                console.log("Fieldtype " + fieldType + "not found");
                return "";
        }
    }

    // NEW and EDIT FORM default field rendering.
    if (controlMode == 2 || controlMode == 3) {
        switch (renderCtx.CurrentFieldSchema.FieldType) {

            case 'Text':
                return SPFieldText_Edit(renderCtx);
            case 'Number':
                return SPFieldNumber_Edit(renderCtx);
            case 'Integer':
                return SPFieldNumber_Edit(renderCtx);
            case 'Boolean':
                return SPFieldBoolean_Edit(renderCtx);
            case 'Note':
                return SPFieldNote_Edit(renderCtx);
            case 'Currency':
                return SPFieldNumber_Edit(renderCtx);
            case 'File':
                return SPFieldFile_Edit(renderCtx);
            case 'Calculated':
                return SPField_FormDisplay_Empty(renderCtx);
            case 'Choice':
                return SPFieldChoice_Edit(renderCtx);
            case 'MultiChoice':
                return SPFieldMultiChoice_Edit(renderCtx);
            case 'Lookup':
                return SPFieldLookup_Edit(renderCtx);
            case 'LookupMulti':
                return SPFieldLookup_Edit(renderCtx);
            case 'Computed':
                return SPField_FormDisplay_Default(renderCtx);
            case 'URL':
                return SPFieldUrl_Edit(renderCtx);
            case 'User':
                return SPClientPeoplePickerCSRTemplate(renderCtx);
            case 'UserMulti':
                return SPClientPeoplePickerCSRTemplate(renderCtx);
            case 'DateTime':
                return SPFieldDateTime_Edit(renderCtx);
            case 'Attachments':
                return SPFieldAttachments_Default(renderCtx);
            default:
                console.log("Fieldtype " + fieldType + "not found");
                return "";
        }
    }

    // VIEW default field rendering.
    if (controlMode == 4) {

        //Copy Paste of Jim Browns awesome helper function to return default View CSR field rendering

        var renderingTemplateToUse = null;

        var fieldRenderMap = {
            Computed: new ComputedFieldRenderer(field.Name),
            Attachments: new AttachmentFieldRenderer(field.Name),
            User: new UserFieldRenderer(field.Name),
            UserMulti: new UserFieldRenderer(field.Name),
            URL: new UrlFieldRenderer(field.Name),
            Note: new NoteFieldRenderer(field.Name),
            Recurrence: new RecurrenceFieldRenderer(field.Name),
            CrossProjectLink: new ProjectLinkFieldRenderer(field.Name),
            AllDayEvent: new AllDayEventFieldRenderer(field.Name),
            Number: new NumberFieldRenderer(field.Name),
            BusinessData: new BusinessDataFieldRenderer(field.Name),
            Currency: new NumberFieldRenderer(field.Name),
            DateTime: new DateTimeFieldRenderer(field.Name),
            Text: new TextFieldRenderer(field.Name),
            Lookup: new LookupFieldRenderer(field.Name),
            LookupMulti: new LookupFieldRenderer(field.Name),
            WorkflowStatus: new RawFieldRenderer(field.Name)
        };

        if (field.XSLRender == '1') {

            renderingTemplateToUse = new RawFieldRenderer(field.Name);
        }
        else {

            renderingTemplateToUse = fieldRenderMap[field.FieldType];
            if (renderingTemplateToUse == null)
                renderingTemplateToUse = fieldRenderMap[field.Type];
        }

        if (renderingTemplateToUse == null)
            renderingTemplateToUse = new FieldRenderer(field.Name);

        return renderingTemplateToUse.RenderField(renderCtx, field, listItem, listSchema);
    }

    //No match found for default render.
    console.log("CSR Default Field Render Failed...");
    return "Default Field Render Failed";
}

//Field overrides.  We are pointing them all to the same function but we 
//could have used different functions if we wanted to.
KG.jslink_contactsnew.Templates.Fields = {
    'FirstName': {
        'EditForm': KG.jslink_contactsnew.Functions.overrideFields,
        'NewForm': KG.jslink_contactsnew.Functions.overrideFields
    },
    'Title': {
        'EditForm': KG.jslink_contactsnew.Functions.overrideFields,
        'NewForm': KG.jslink_contactsnew.Functions.overrideFields
    },
    'KGContactType': {
        'EditForm': KG.jslink_contactsnew.Functions.overrideFields,
        'NewForm': KG.jslink_contactsnew.Functions.overrideFields
    },
    'FullName': {
        'EditForm': KG.jslink_contactsnew.Functions.overrideFields,
        'NewForm': KG.jslink_contactsnew.Functions.overrideFields
    },
    'Company': {
        'EditForm': KG.jslink_contactsnew.Functions.overrideFields,
        'NewForm': KG.jslink_contactsnew.Functions.overrideFields
    }
}

//Useless junk fires after each individual field render even fields that dont have an override.
//KG.jslink_contactsnew.OnPostRender = KG.jslink_contactsnew.Functions.fieldOnPostRender;

//KG.jslink_contactsnew.BaseViewID = 1;

//105 is for lists of type Contact
KG.jslink_contactsnew.ListTemplateType = 105;   

//Make the magic happen....
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(KG.jslink_contactsnew);

} $_global_kgjslinkcontactsnew_test(); 

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.