Setting the scene


Client Side Rendering (CSR) is one of the new concepts introduced by Microsoft in SharePoint 2013. With the help of this new feature, you don’t have to write XSLT to style SharePoint elements like list views, fields etc. Using this technique you can use HTML and JavaScript to change the user interface.

As cited in MSDN “Client-side rendering provides a mechanism that you can use to produce your own output for a set of controls that are hosted in a SharePoint page. This mechanism enables you to use well-known technologies, such as HTML and JavaScript, to define the rendering logic of custom field types. In client-side rendering you can specify your own JavaScript resources and host them in the data storage options available to your farm solution, such as the _layouts folder.

Introduction


Client side rendering is like a templating mechanism used to customize the User Interface (UI). 

When we talk about client side rendering, then there are two things that requires a mention here are:
  1. Display Templates
  2. JSLink

Display templates are used in webparts that are based on search technology. They are used for handling the rendering of the search results on the page. We can customize how search results appear to the end user.

The second one i.e. the JSLink, is of what this article will focus on. JSLink is one of the many cool features introduced by Microsoft in SharePoint 2013.
It is a property that is available on many SharePoint objects like content types, lists, views, fields and web part properties. We simply point this property to a JavaScript file that will do a magic on our page.  In other words, will simply transform our page into whatever way we want to render all at the client side.

You might have encountered scenarios where your customers have approached you to display lists with a custom look and feel without writing any piece of code. Consider for example you have a list holding contact details of the users that needs to be displayed in a card like manner as opposed to the traditional screen. And all this has to be done without writing any server side code. Though this might seem to be tricky but it can be achieved very easily using a simple mechanism and i.e. JSLink.

JSLink has tremendous power. It can transform your entire site into an attractive piece without writing any server side code.  It is like an on-off switch. If you don’t like it, you can simply remove the value of the jslink property and you will get back the original default behaviour.

To see the actual strength of this property, let us actually dig some code and cover some scenarios.

Scenario


As discussed above, we can have JSLink attached to multiple things like a field, view etc. In the scope of this article, let us target the list view. 

Let us take up a very simple scenario. We would like to display users who have completed 5 years, 10 years, 15 years and 20 years in the job. In order to cover different scenarios, let us also show the department the user belongs to, assuming this to be a lookup column.

Approach


In order to keep things simple, let us assume that the target audience can create site columns and content type for our Anniversary list.

 Create site columns for the below fields.
  • UserName (User type)
  •  Department (Lookup on department list)
  • Hired Date (Date type)
  • Anniversary Category (in years)  (Choice type e.g. 5,10,15,20)
  • Total Years (Calculated column) Formula is “=[Anniversary Category (in years)] + 0”
We have the calculated column as we require this for grouping purpose which we will discuss in a while.

We will here create a list schema with a custom view. We can do it manually through UI also but let us do that using visual studio. The reason why we are doing it through visual studio is to focus on the jslink property that is available in the schema.




If you open the schema.xml, then by default the following views will be visible.



Let us expand the second view and observe the XML over there. As highlighted in the below screenshot, you will see that there is one new tag over there i.e. the JSLink. The value of this is shown as clienttemplates.js which is the default JavaScript file. Also we have highlighted the BaseViewID here. 



Now let us go back to the designer view of the list definition and create a custom view here. The reason for this is that we want to attach our custom jslink file to the list view.

There are other options as well to do this like manual or using PowerShell. But let us take up this approach.



Let us open the schema.xml file and see what changes are done to it.



As you can see in the screenshot above, a new view is added with a BaseViewID of 2. This is our “All Anniversary Items” view. It also refers to the same default jslink file.

Also make sure that in schema.xml file you mention the GroupBy collapse.

<Query>
      <GroupBy Collapse="FALSE" >
          <FieldRef Name="TotalYears" Ascending="FALSE" />
       </GroupBy>
</Query>

Now, what we want is that if a user clicks on the anniversary list, then in the “All Anniversay Items” view, it should render our custom UI rather than the default behaviour. In order to achieve this, let us first create a JavaScript override file.  You can put this file in Master Page Gallery, Style Library or in the layouts folder depending upon your scenario. 

Then the next step is to write your code in this JavaScript file.

// Create a namespace for our functions so to avoid conflicts
var anniversaryNS = anniversaryNS || {};
 
//The rendering logic is written here
anniversaryNS.anniversaryItem = {
    customItemHtml: function (ctx) {
 
        var anniversary = {};
        anniversary.CelebrationYear = ctx.CurrentItem.TotalYears;
        anniversary.Name = "";
        anniversary.Department = "";
 
        //Handling User Type site column
        if (ctx.CurrentItem.UserName[0] != undefined && ctx.CurrentItem.UserName[0] != null && ctx.CurrentItem.UserName[0] != "") {
            anniversary.Name = ctx.CurrentItem.UserName[0].title;
        }
 
        //Handling lookup site column
        if (ctx.CurrentItem.Department[0] != undefined && ctx.CurrentItem.Department[0] != null && ctx.CurrentItem.Department[0] != "") {
            anniversary.Department = ctx.CurrentItem.Department[0].lookupValue;
        }
 
        anniversary.HiredDate = ctx.CurrentItem.HiredDate;
 
        //Building the html
        var anniversaryItemHtml = "<div class='anniversaryDiv'><div><p class='font14'>" + anniversary.Name + "</p>";
        anniversaryItemHtml += "<p class='font12'>" + anniversary.Department + "</p>";
        anniversaryItemHtml += "<p class='font12'>Joining Date: " + anniversary.HiredDate + "</p></div></div><hr class='horiAnniversary'  />";
 
        return anniversaryItemHtml;
    },
    customGroup: function (ctx, group, groupId, listItem, listSchema, level, expand) {
        var html = '<div><h3>' + listItem[group] + ' Years </h3></div>';
 
        return html;
    }
};
//This is a self invoking function.
//Here we are customizing the header, item and group.
(function () {
    var ctxAnniversary = {};
    ctxAnniversary.Templates = {};
 
    ctxAnniversary.Templates.Header = "<div></div>";
    ctxAnniversary.Templates.Item = anniversaryNS.anniversaryItem.customItemHtml;
    ctxAnniversary.Templates.Group = anniversaryNS.anniversaryItem.customGroup;
    ctxAnniversary.BaseViewID = 82; //Make a note of this
 
    ExecuteOrDelayUntilScriptLoaded(function () {
 
        var oldRenderListView = RenderListView;
 
        RenderListView = function (ctxAnniversary, webPartID) {
 
            if (ctxAnniversary.ListTitle == "Anniversary") {
 
                ctxAnniversary.BaseViewID = 82;
            }
 
            oldRenderListView(ctxAnniversary, webPartID);
 
        }
 
    }, "ClientTemplates.js");
 
    //Register our override object with SharePoint using RegisterTemplateOverride method
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ctxAnniversary);
})();

The anonymous function above is creating our override object. This object takes the following properties.
  • Group
  • Item
  • View
  • Header
  • Body
  • Footer
  • Fields
  • OnPreRender
  • OnPostRender
You can verify the same while debugging your JavaScript file. If you have a look at the clienttemplates.js file that is used for OOTB rendering then you can see the following code over there.



What we have done in the JavaScript file above is that we have created a namespace first to avoid any naming conflicts. After that we have written couple of methods that hold the rendering logic for us. You can see that in customItemHtml  we have written the logic to render the UI  template for item and in customGroup we have written the grouping template. After this the JavaScript shows the self invoking method that creates our override object. There we define the templates that we are going to modify. If you look closely you can observe that for rendering Item and Group template we are making calls to our custom functions. The final piece is to register our override object with SharePoint using the RegisterTemplateOverrides method call.

 Once we have created our js file, let us go back to schema.xml file and do the relevant changes.



As you can see in the above screenshot, we have done two changes to this schema. First we changed the BaseViewID to 82 and secondly we changed the JSLink node to point to our custom js file.

Now, once you are done with all these changes you are good to go. Deploy the solution to your site and populate some data in your newly created Anniversary list. 

You can see there are two views in this list, “All Items” and “All Anniversary Items”.

This is the default “All Items” view.



Now if you click on “All Anniversary Items”, it will render your custom view. If you have a look at the below screenshot, it completely changes the look and feel of the view.  

Just with the help of JavaScript and HTML, you have been to completely change the look and feel of the OOTB screen.



Now if we want to display the count of users in each category, let us modify our rendering logic a little bit for the custom group.

customGroup: function (ctx, group, groupId, listItem, listSchema, level, expand) {
        var html = '<div><h3>' + listItem[group] + ' Years (' + listItem[group + ".COUNT.group"] + ')</h3></div>';
 
        return html;
}

Now if you deploy the changes and have a look at the list view you will see something like below



If you have a look at the above screenshot, it also shows you count against each category. 

Let us consider another scenario where you have an Announcements List and want to show a new icon against the newly added announcements. Let us see how this can be achieved.

To keep things simple, let us assume that you have created an Announcements list with a custom view and have added a jslink to the same. Also you have done the required UI rendering stuff similar to what you have done in the Anniversary list.

Now, for the new icon what you need to do is to write the below piece of code in your html for your item template.

announcement.IfNew = ctx.CurrentItem["Created_x0020_Date.ifnew"];
var announcementItemHtml = "";
 
        if (announcement.IfNew == "1") {
            announcementItemHtml = "<div class='announcementDiv'><div><div class='floatLInline'><h2>" + announcement.Title + "</h2></div><div class='announcementDateStyle' ><span>" + announcement.PostedDate + "</span><img src='/_layouts/15/1033/images/new.gif' alt='New'/></div></div>" + html + "</div>";
        } else {
 
            announcementItemHtml = "<div class='announcementDiv'><div><div class='floatLInline'><h2>" + announcement.Title + "</h2></div><div class='announcementDateStyle' ><span>" + announcement.PostedDate + "</span></div></div>" + html + "</div>";
}

If you look at the above piece of code, we have first made use of ctx.CurrentItem["Created_x0020_Date.ifnew"]. Here Created_x0020_Date.ifnew returns the value “1” if it is a newly added icon. Based upon the value returned we are simply rendering the html to show a new icon image or not.

The screenshot below shows how it gets rendered.



See how simple it was to show a new icon against the recently added announcement.

Conclusion


JSLink is a very powerful and useful feature introduced in SharePoint 2013. It can transform your entire site into an attractive piece without writing any server side code.
The steps involved to achieve the customized look and feel are very simple as well. To summarize, we have basically done the following things
  1. Created list definition and added a custom view.
  2. Created a JavaScript File.
  3. Modified the BaseViewID and JSLink property in schema file.
  4. Deploy and test.

References

See Also