Client Side Rendering "Custom Field"

Target:
In SharePoint development make your change as least as can to make customization simple and don't lost any SharePoint features.
If you want to change field displaying in SharePoint list forms, this don't mean replace all list forms make it simple by replacing field html only. Client Side Rendering (CSR) will help us to do this.

Prerequisites:
  • Javascript
  • JSOM.
Business Cases Details:
In this demo I want to create color field which is a picker in new/edit form ,colored div in view/display form and picker in quick edit mode.

Demo:
To make this solution reusable i have 2 approach :
  1. Add new type for fields in SharePoint (see this post How to create custom field type in SharePoint ?).
  2. Create site column with CSR. Site column have an advantage in search because all site columns mapped as managed property.
In this demo i will go with the 2nd solution "Site Column". 
  1.  Create the farm solution project with name "CsrDemo".
  2.   Add new item to project from SiteColumn Template with name "ColorColumn".
  3. Add module item template to project with name "ColorColumnJsModule" to upload JavaScript file in Asset library which responsible for displaying field in different forms.
  4. Add JavaScript file into the module make file name "ColorCsr.js".
  5. The project will be as following:

Site column file :
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">  
  <Field
       ID="{daca1f8b-01e2-47e8-b779-663b07e3209e}"
       Name="ColorColumn"
       DisplayName="Color Column"
       Type="Text"
       JSLink="~siteCollection/SiteAssets/ColorCrs.js"
       Required="FALSE"
       Group="Custom Site Columns">
  </Field>
</Elements>
JSLink="~siteCollection/SiteAssets/ColorCrs.js"
this attribute is a link for JavaScript file deal with field rendering in different forms. The token ~siteCollection refer to the current site collection URL. (use ~site token when js file is located in list existing in sub site).


Module file :
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="ColorColumnJsModule" Url="SiteAssets">
    <File Path="ColorColumnJsModule\ColorCrs.js"
          Type="GhostableInLibrary"
          Url="ColorColumnJsModule/ColorCrs.js" />
  </Module>
</Elements>
Type="GhostableInLibrary"
GhostableInLibrary mean put this file in library not in folder this files will served by VirtualPathProvider in ASP.Net. 



JavaScript file
/// <reference path="E:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\LAYOUTS\clienttemplates.js" />

(function () {
    var newCtx = {};
    newCtx.Templates = {};
    newCtx.Templates.Fields = {
        ColorColumn: {
            View: renderView,
            DisplayForm: renderView,
            NewForm: renderEdit,
            EditForm: renderEdit
        }
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(newCtx);
})();

function renderView(x, b) {
    if (x.inGridMode) {
        b.AllowGridEditing = false;
        return "<input type='color' id='myColor" + x.CurrentItem.ID + "' onchange='test(this);' value='" + x.CurrentItem.ColorColumn + "' />";
    }
    return "<div style='width:20px;height:20px;background-color:" + x.CurrentItem.ColorColumn + "'></div>";
}

function test(ele) {
    var id = ele.id.split("myColor")[1]
    var x = document.getElementById("myColor" + id);
    var currentVal = x.value;

    var clientContext = new SP.ClientContext();
    var oWebsite = clientContext.get_web();
    //ctx is the current context
    var item = oWebsite.get_lists().getByTitle(ctx.ListTitle).getItemById(id);
    item.set_item('ColorColumn', currentVal);
    clientContext.load(item);
    item.update();

    clientContext.executeQueryAsync(sucess, faild);

    function sucess() {
    }

    function faild() {

    }

}
function renderEdit(x) {
    var form = SPClientTemplates.Utility.GetFormContextForCurrentField(x);
    form.registerGetValueCallback(form.fieldName, function () {
        return document.getElementById("colorField").value;
    })
    var html = "<input type='color' id='colorField' value='" + x.CurrentItem.ColorColumn + "' />"
    return html;
}
Client Side Rendering (CSR) concept:
Page have main JavaScript object called context ,this context responsible for render fields, render views and another tasks. Each field in SharePoint have its template which context use it to render field in different forms, i want to override this template in the current context.
To make this done Microsoft provide a JavaScript function "SPClientTemplates.TemplateManager.RegisterTemplateOverrides" to override current context.
First create new object with any name "var newCtx = {};" and add properties which you want to override with the same name in current context.
Second pass the newCtx object to this function RegisterTemplateOverrides to replace old properties by your properties.

Result Will be:




Color column in all forms after added in "Attendance Status" list:







1 comments :

تصميم المواقع أفضل الممارسات التي يقوم بها أصحاب الأعمال اليوم يمكنك الأن
تصميم مواقع
تصميم متجر الكتروني

Reply

Post a Comment