Tuesday, September 30, 2014

Client Side Rendering using JSLink – Post 03 – Properties to override

Introduction

Read my first two post in order to get basics idea on Client Side rendering using JSLink.

In last two post we discussed basics on JSLink. Now lets look bit deeper. In this post I will illustrate; what are the fields we can override and use in template. I will give you examples for each and every property. Below are the properties that we can use to override in our custom template.

  • Header
  • Footer
  • View
  • Body
  • Group
  • Item
  • Fields
  • OnPreRender
  • OnPostRender

I have created an announcement list instance in order to illustrate the examples. My list instance displays as follows. Please note that I have grouped the list items by Created.

image

I have linked my JavaScript file for the above list instance. Now lets get into the examples.

Header

Overrides the Header of the list instance. The header area is described by the below image.

image

Code
  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.  
  6.     // Change the header
  7.     overrideCtx.Templates.Header = "<b>This is a custom header</b>";
  8.  
  9.     // Register the template overrides.
  10.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  11. })();

Results

image

Footer

We can add a footer in the list instance.

image

Code
  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.  
  6.     // Change the footer
  7.     overrideCtx.Templates.Footer = "<b>This is a custom footer</b>";
  8.  
  9.     // Register the template overrides.
  10.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  11. })();
Results

image

Fields

Visit my first blog post and see the example. You can understand how to override the fields. If you want to retrieve the actual value of a field you can retrieve by  “<#= ctx.CurrentItem.FieldName#>” or by ctx.CurrentItem.FieldName.

Code
  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.  
  6.     overrideCtx.Templates.Fields = {
  7.         'Body': { 'View': '<div style="color:red; background-color: green"><#= ctx.CurrentItem.Body #></div>' }
  8.     };
  9.  
  10.     // Register the template overrides.
  11.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  12. })();
Results

image

Group

Overriding Group takes 7 parameters. Using those parameters you can change the look and feel of the group. I will just show you a basic.

Code
  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.  
  6.     overrideCtx.Templates.Group = customGroup;
  7.     // Register the template overrides.
  8.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  9. })();
  10.  
  11. function customGroup(ctx, group, groupId, listItem, listSchema, level, expand) {
  12.     var html = '<div style="color:red">' + listItem[group] + ' </div>';
  13.     return html;
  14. }
Results

image

Body

Overrides the body.

Code
  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.  
  6.     overrideCtx.Templates.Body = customBody;
  7.     // Register the template overrides.
  8.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  9. })();
  10.  
  11. function customBody(ctx) {
  12.  
  13.     return String.format("Hello world from {0}", ctx.ListTitle);
  14.  
  15. }
Results

image 

Item

The Item template points to the function that displays each Item in the list.

Code

  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.    
  6.     overrideCtx.Templates.Header = "<B><#=ctx.ListTitle#></B>" +
  7.         "<ul>";
  8.  
  9.     // This template is assigned to the CustomItem function.
  10.     overrideCtx.Templates.Item = customItem;
  11.     overrideCtx.Templates.Footer = "</ul>";
  12.  
  13.  
  14.  
  15.     // Register the template overrides.
  16.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  17. })();
  18.  
  19. // This function builds the output for the item template.
  20. // It uses the context object to access announcement data.
  21. function customItem(ctx) {
  22.     // Build a listitem entry for every announcement in the list.
  23.     var ret = "<li>" + ctx.CurrentItem.Title + "</li>";
  24.     return ret;
  25. }

Results

image

OnPreRender

OnPreRender event fires before the DOM is loaded. In my example I will show how to set a custom list name.

Code
  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.  
  6.     //Over ride the header
  7.     overrideCtx.Templates.Header = "<#=ctx.ListTitle#>";
  8.  
  9.     //Set the List title on pre render event
  10.     overrideCtx.OnPreRender = function a() {
  11.         ctx.ListTitle = "Title from PreRender";
  12.     };
  13.  
  14.     // Register the template overrides.
  15.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  16. })();
Results

image 

OnPostRender

OnPostRender event fires after DOM is loaded. So you can change the values after DOM load. Here in our example I have changed the background color.

Code
  1. (function () {
  2.     // Initialize the variable that stores the objects.
  3.     var overrideCtx = {};
  4.     overrideCtx.Templates = {};
  5.     //OnPostRender call postRenderHandler function.
  6.     overrideCtx.OnPostRender = postRenderHandler;
  7.  
  8.     // Register the template overrides.
  9.     SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
  10. })();
  11. function postRenderHandler(ctx) {
  12.     var rows = ctx.ListData.Row;
  13.     for (var i = 0; i < rows.length; i++) {
  14.         var isApproved = rows[i]["Title"] == "Title 001";
  15.         if (isApproved) {
  16.             var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
  17.             var tr = document.getElementById(rowElementId);
  18.             tr.style.backgroundColor = "#ada";
  19.         }
  20.     }
  21. }
Results

image `

Conclusion

So the basics are covered and if you are familiar with JavaScript and CSOM you can do more on Client side rendering with JSLink.  In future posts I will show some examples how you can use client side rendering.

16 comments:

  1. Great post ! Thank you !
    I would like to customize the header of a listview but keeping the header columns. How can I achieve this ? Where are the files SharePoint used to render header ?

    ReplyDelete
  2. Nice post. It has details information about customizing List using JS Link.

    ReplyDelete
  3. what if i have two listviews on the same page and I want to render the second one however the first one is being rendered instead?

    ReplyDelete
    Replies
    1. I think this post may help you. In case if it didn't workout just inform; I'll give a try.
      http://therelentlessfrontend.com/2014/05/01/having-multiple-jslink-based-webparts-on-the-same-page-overrides-all-the-other-templates-in-sp-2013/

      Delete
  4. Hi, I am trying to apply jslink to a that I created for the discussion list. I can-t get to work the overriding for Fields and neither Item. It never executes the code inside the functions. What can be wrong?
    function WaitRegisterCustomview(){
    SP.SOD.executeOrDelayUntilScriptLoaded(_RegisterCustomView, 'clienttemplates.js');
    }
    function _RegisterCustomView() {

    var viewContext = {};
    viewContext.Templates = {};
    viewContext.BaseViewID = 3;
    viewContext.ListTemplateType = 108;
    viewContext.Templates.Header = 'custom header';
    viewContext.Templates.Fields = {
    'Subcategory': { 'View':
    function(ctx){
    return 'custom text';
    }
    },
    'Body':{'View':'Test body'}
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(viewContext);

    }

    ReplyDelete
    Replies
    1. As I know JS link is not working for Discussion and Calendar. If you get any solutions please let me know.

      Delete
    2. JS Link will work for Calendar and discussion.Only thing is that it wont work for the Calendar View as such .It will very well work with the All Items view of the calendar. Same case with Discussion borad.

      Delete
  5. Very good post!
    I am trying to figure out how to make a custom template for displaying a item, supposing it has 3 fields, Title, Shape and Color.

    DIV.BOX
    _H1 ctx.[].Title /H1
    _DIV
    __DIV.LEFT ctx.[].Shape /DIV
    __DIV.RIGHT ctx.[].Color /DIV
    _/DIV
    /DIV

    Do I have to conjugate
    Templates.Body and Template.Item?

    I am coding to SPO, no Server available to me in VSTO and I could not find MSDN / Technet references on SPClientTemplates.TemplateManager ...

    Can u help me? any link would be appreciated.

    Thank u!!

    ReplyDelete
  6. I am facing a problem with JSlink. I need to use both Field override in a group by view which is being rendered using Item Override . In short I am trying to use Field override in a view being rendered using Gruop overide and Item override.

    Field override alone is working for me. But when i use it with the Group over ride and Item override, it fails.


    itemCtx.Templates.Header = headers;
    itemCtx.Templates.Group = groupfun;
    itemCtx.Templates.Item = itemfun;
    itemCtx.Templates.Fields = { "Advisory": { "View": renderSymbol } };

    ReplyDelete
  7. Anyway someone can help ?I actually got a workaround,I removed the field override and handled the rendering of the field in item override function. But I need to know if its the case that either we should use field override or item override-and both donot work at one go ! .Thanks in advance.

    ReplyDelete
  8. Hi, I want to customize list's fields. Item and header override works, but field overrode not working. Even the field override event handler not triggered.

    ReplyDelete
  9. hi, i want to add data in multiline text type column, guide me how to do it using CSR.

    ReplyDelete
  10. It is perfect time to make some plans for the future and it is time to be happy. I've read this post and if I could I desire to suggest you some interesting things or suggestions. Perhaps you could write next articles referring to this article. I want to read more things about it!USB名入れ

    ReplyDelete
  11. hi
    If I use this text "overrideCtx.OnPreRender = window.ImprovedListView.Paging.onPreRender;"

    and overrideCtx.OnPostRender will not work.
    Can you tell me why, thank you!

    ReplyDelete