Navigation

Thursday, 22 August 2013

JSLink and Display Templates Part 2 - Changing how individual fields display

This is part two in my JSLink and Display Template series, and in this post we will be looking at the actual Display Template JavaScript code to override the rendering of individual fields.
If you haven't read Part 1 and then it is well worth a look, if nothing else you need to understand the URL tokens and where/how you use JSLink to get your Display Template in the right place.

So what will we be doing?
The premise of using Display Templates here is simple, we are going to tell SharePoint
that when it wants to render a field we want it to use one of our JavaScript functions instead of the "out of the box" one.

We can do this on each field for four different rendering methods:
  • Display Forms
  • Edit Forms
  • New Forms
  • Views (as in, list views)
 This post will look at the "Display Form" while the others are covered in further posts in this series.

Registering your Override Methods
The magic all happens through a SharePoint JavaScript method called SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ctx). This expects a single object to be passed in which declares what exactly we want to override.
This method call is actually the same we use throughout this series, but in this example we will focus on the Fields part of it.
In order to do this we need to create an object which has an empty "Templates" object value. This "Templates" object then contains a "Fields" object value which contains an array specifying the fields we want to override. Each field override then refers to methods which contains the rendering logic for that field.

We finally pass our main object over to the RegisterTemplateOverrides method and let SharePoint take care of the rest. For example:

(function() {
  var mjhOverrides = {};
  mjhOverrides.Templates = {};
  mjhOverrides.Templates.Fields = {  
    'MyCustomField': {
      'DisplayForm': mjh.displayMethod
    }
  };
 
  SPClientTemplates.TemplateManager.RegisterTemplateOverrides(mjhOverrides );
})();

So in the example code above we create our override object called "mjhOverrides" (which has a "Templates.Fields" value).  We then assigned an array (of one item) which specified the InternalName of the field I want to override (in this case "MyCustomField").

I then specified that when SharePoint wants to render this field for a "Display Form" then I want it to use my own method called "mjh.displayMethod"

The whole thing is wrapped in an anonymous self-executing function so that it executes as soon as the page is loaded but doesn't pollute the global namespace.

Of course, you could specify multiple different fields or multiple different override methods, this uses simple JavaScript array principles and an example is shown below:

mjhOverrides.Templates.Fields =
{ 
  'MyCustomField: {
    'DisplayForm': mjh.displayMethod,
    'View': mjh.viewMethod
  }, 
  'Title': {
    'DisplayForm': mjh.displayMethod,
    'View': mjh.viewTitleMethod
  }
};

So in the above example we are overriding two different fields (a custom field called "MyCustomField" and the out of the box "Title" field). For each field we specify overrides for both the DisplayForm and the View (List View) methods.

Note that we can re-use the same rendering method multiple times for different fields (so it is highly recommended to try and build reusable generic render methods where possible).

Format of a Render Method
So now that we have told SharePoint which render method we want it to use I suppose it would be useful to actually write it. Being a good JavaScript citizen we declared our own namespace for our functions so we didn't pollute the global namespace, so the function starts off with a simple method declaration.

var mjh = mjh || {};

mjh.displayMethod = function (ctx) {
  return '<div>Hello World</div>';
}

The format as you can see is very simple. All we need to do is return a string which contains the HTML we want to display. This example is not particularly useful as every item will render the same HTML (a simple Hello World message).

Hopefully you can appreciate that with the power of JavaScript and CSS you really do have full-reign to do whatever you want here. You can declare JavaScript events for AJAX REST calls or simply using some CSS and jQuery to create a funky dynamic interface (or just output some nice clean HTML).

However, this example isn't terribly useful as what we REALLY want are access to the item values, and this is where the "ctx" object comes in. This is a method argument which SharePoint automatically provides and is a "Render Context" object.

Now I really haven't been able to find very much information on MSDN / TechNet (read - actually I've found nothing) which describes this object and all of its methods, but from inspecting the JavaScript object using the developer tools I've managed to gleam a fair bit of detail. I've listed the basic values below, but to be honest you'd get a lot of value by poking around in the script debugger and checking out this object in more detail.

// value of the current field
var currentValue = ctx.CurrentFieldValue;

// the list item object
var item = ctx.CurrentItem;

// get the schema for the field
var field = ctx.CurrentFieldSchema;

So in order to make our display method a little more useful we should update it to the following:

mjh.displayMethod = function (ctx) {
  return '<div class='mjhCustomField'>' + ctx.CurrentFieldValue + '</div>';
}

 So now we have our item being displayed in a custom div with our own class. We can of course properly go to town on this but you get the idea :)

This is all then wrapped into a JavaScript file and attached either to the Site Column (declaratively in XML) or the List Form Web Part, or the Content Type (for more information on how to do that please go and read Part 1).

So that is about as complicated as it gets for Display Forms, but don't worry, we have all sorts of fun and games coming up in the next parts in the series, first creating custom editing interfaces, providing validator methods and overriding views.

...

Next : Part 3 - Creating a custom editing interface

No comments:

Post a Comment

This blog has been moved to www.martinhatch.com

Note: only a member of this blog may post a comment.