In this post we will see the different ways to apply templates to a Telerik Kendo UI grid column. We will start by creating a sample grid, applying a simple template, and then move the generation of the content to render to a function that we will call from the template.

Before we start we will create a simple Kendo UI grid sample using AngularJS, and then we will proceed to add templates to certain columns.

Creating a basic Kendo UI AngularJS grid

For starters we will create the HTML markup for our Kendo UI grid, the AngularJS application, and the controller::

<div ng-app='formatDemo'>
<div ng-controller='productionCtrl'>
        <kendo-grid options='mainGridOptions'>
        </kendo-grid></div>
</div>

We need some data to display in the grid. In real life we will get our data from a REST service, for example, such as the one described in this post about adding a Web API to an ASP.NET project. But for this example we are simply going to create some hard-coded example data using Telerik’s Kendo UI datasource:

     var productsDataSource = new kendo.data.DataSource({
        data: [
            {Product:'Capuccino',Qty:1000,Price:2, Objective:700},
            {Product:'Espresso',Qty:200,Price:2, Objective:700},
            {Product:'Moccha',Qty:800,Price:3, Objective:1000},
            {Product:'Frappe',Qty:700,Price:4, Objective:1000},
            {Product:'Latte',Qty:600,Price:3, Objective:1000},
            {Product:'Bagel',Qty:800,Price:4, Objective:800},
            {Product:'Croissant',Qty:900,Price:5, Objective:600},
            {Product:'Cake',Qty:20,Price:8, Objective:500},
        ]
    });

Finally we will add the necessary JavaScript to create the grid:

    angular.module('formatDemo', [ 'kendo.directives' ])
        .controller('productionCtrl', function($scope){
            $scope.mainGridOptions = {
                dataSource: productsDataSource,

                columns: [{
                    field: 'Product',
                    title: 'Product'
                    },{
                      field: 'Qty',
                      title: 'Quantity'
                    },{
                      field: 'Price',
                      title: 'Price'
                    },{
                      field: 'Objective',
                      title: 'Income Objectives'
                    }]
                  };
    });

At this point our grid looks like this:

Kendo UI grid

Using Kendo UI templates in grids

Now we have a functionally Kendo UI grid and we can start to apply templates to the columns.

Hash literals

We add the attribute template to a column to define the template to be used. Also we will use hashtags to do the following:

  • Render the values in the template
  • Execute JavaScript code in our template.

For example we can use a template to represent the price column in bold characters. It’s as simple as this:

{
  field: 'Price',
  title: 'Price',
  template:'<b>#= Price #</b>'
}

Notice how we used #= # to represent where the price should be rendered in our template.

We can also use templates to create calculated columns. For example, let’s add a new column representing the total income for each product:

{
  field: null,
  title: 'Total',
  template: '#= Price * Qty #'
}

As an example of how to include JavaScript in our template we can do, for example, this:

{
field:null,
template: '# if ((Price * Qty) > Objective) { # ' + '<span> : -) </span>' + '# } else { #' + ' #= Price * Qty # (: -()' + '# }#'
}

The above code will add a column that will display a smiling face if the total income is above the objective, and the actual total income accompanied by a sad face when it’s not so:

Kendo UI grid after applying the formes templates
Uhm … one could say things are not looking good for espresso and cake sales.

How to use function inside a Kendo UI template

I am sure you noticed that our last template was anything but easy to read. The basic #= # syntax is fine when we are working with simple templates as was the case with our first examples. When we need to add logic and conditions, though, it quickly becomes a mess.

Let’s see how we can move our logic to an external function. To do that we need to know how to call a function from a template and how to access the current row data model from the function.

To call a function from a template we use the syntax we have already seen:

{
field:null,
template: '#=generateObjectivesTemplate()#'
}

When using templates, the current row datamodel is passed to the template as an object called data. Since in our example we are using the variables Price, Qty and Objective to determine the output to be rendered, we can modify the function like this to pass these variables as parameters:

{
field:null,
template: '#=generateObjectivesTemplate(data.Price,data.Qty,data.Objective)#'
}

Now the only thing left to do is to implement the generateObjectivesTemplate function:

function generateObjectivesTemplate(Price,Qty,Objective)
{
          if ((Price * Qty) > Objective)
          {
            return '<span> : -) </span>'
          }
          else
          {
            return (Price * Qty)+'<span> (: -() </span>'
          }
}

In summary our code would look like this:

<script>
function generateObjectivesTemplate(Price,Qty,Objective)
{
          if ((Price * Qty) > Objective)
          {
            return '<span> : -) </span>'
          }
          else
          {
            return (Price * Qty)+'<span> (: -() </span>'
          }

}
        var productsDataSource = new kendo.data.DataSource({
                       data: [
                         {Product:'Capuccino',Qty:1000,Price:2, Objective:700},
                         {Product:'Espresso',Qty:200,Price:2, Objective:700},
                         {Product:'Moccha',Qty:800,Price:3, Objective:1000},
                         {Product:'Frappe',Qty:700,Price:4, Objective:1000},
                         {Product:'Latte',Qty:600,Price:3, Objective:1000},
                         {Product:'Bagel',Qty:800,Price:4, Objective:800},
                         {Product:'Croissant',Qty:900,Price:5, Objective:600},
                         {Product:'Cake',Qty:20,Price:8, Objective:500},
                       ]
                   });

                   angular.module('formatDemo', [ 'kendo.directives' ])
                     .controller('productionCtrl', function($scope){
                         $scope.mainGridOptions = {
                             dataSource: productsDataSource,

                             columns: [{
                                 field: 'Product',
                                 title: 'Product'
                                 },{
                                 field: 'Qty',
                                 title: 'Quantity'
                                 },{
                                 field: 'Price',
                                 title: 'Price',
                                 template:'<b>#= Price#</b>'
                                 },{
                                 field: 'Objective',
                                 title: 'Income Objectives'
                                 },
                                 {
                                 field: null,
                                 title: 'Total',
                                 template: '#= Price * Qty #'
                              },
                              {
                              	field:null,
                               template:'#= generateObjectivesTemplate(data.Price,data.Qty,data.Objective) #'

                              }]
                         };
                     })
</script>

Conclusion

Our first attempt at a data grid table had a lot of room for improvement from an end user usability point of view. It displayed the raw data as it was, but the presentation was a bit of a bore and it didn’t allow to detect important data at a quick glance.

In this article we have seen how we change that by applying templates to the grid columns. Although the examples we have used in this article are very plain, we can create more spectacular displays using the same simple principles.

Also in a real life application that would be bigger and include many lines of code we would have organized our code in modules, using any of the JavaScript patterns that exist for this purposes (module pattern, and revealing pattern come to mind). If you are using ES6 you would use ES6 modules.

Also our original sample could benefit not only of applying templates to the columns, but also format, but that´s a subject for a different post 🙂

As your templates grow in complexity you may also move from the kind of inline templates we have seen in this post to using Kendo UI external templates.

Thanks for reading. If you find this tutorial useful you can click in the “follow” button at the end of the post to be notified of new posts.

Advertisements