Kendo UI Templates use a simple templating syntax we call "hash templates."

Hey, Telerik~ A quick word to the wise: It's probably worth including a link to where you actually explain that syntax everywhere you have a template property in your examples.

The info at their API docs for column templates is okay, but not great. The info at their templating explanation is pretty crucial for you to understand live examples of customizing grid display.

The four grid column template/rendering formats

Let's quickly list the different ways to produce column names and values.

  1. Column name and value spit directly into the column.
    • columns: [ "id", "field1", "field2" ]
  2. Change the title to whatever you want.
    • columns: [ "id", { title: "Whatever I want", field: "field1" } ]
  3. Use a Telerik template.
    • { title: "File Preview", template: '<img src="#:field3#" alt="Thumbnail for asset id \\##:id#"" />' },
    • This is a little messier than the others. Note the "hash template" format.
    • You put whatever column value you want after the #:, sort of like a Razor template.
    • Then close with another #.
    • To escape a "real" #, you can use \\#, an escaped escape char (\), then the #.
    • Again, their full docs on templating are here.
  4. Use a javascript function.
    • template: function(dataItem) { return "<strong>" + kendo.htmlEncode(dataItem.name) + "</strong>"; }
    • Note here that dataItem is just whatever's on the row.
    • There are no built-in properties I can find other than dirty and uid.
    • dirty is a boolean if the value's been changed, I assume.
    • uid is a GUID.
      • Honestly, I'm not sure where uid comes from, other that that's it's obviously Telerik.
      • That is, uid is not in my JSON payload.
    • NOTE: Functions don't work for title.
      • Blows up at a replace call.
      • From the telerik minimized code:
        • f.title&&(e+=i.attr("title")+'="'+f.title.replace(/'/g,"'")+'" '),

Quick critique ;^)

Though I don't mind overloading parameters, at some point, it seems like you should've sunk your time into one or the other -- either allow functions or develop some crazy templating system. Personally, I prefer number four over three, as it doesn't require any Telerik-specific knowledge.

Telerik has an interesting way of creating sort of simplest case examples, but would benefit from a sort of kitchen sink style demo that slowly builds on itself of the grid. "Here's a grid with a straight column, a column with a formatter, and a column with template." You know, like this:

Composite example with each column renderer type

$(document).ready(function() {
    $("#gridTest").kendoGrid({

        //==========================================
        // Methods to produce columns.
        //==========================================
        columns: [
        // 1. Raw column name and value.
            "id",
        // 2. Change title, raw value.
            { title: "Whatever I want", field: "field1" },
        // 3. Use a Telerik template for value.
            {
                title: "File Preview", 
                template: '<img src="#:field2#" alt="Thumbnail for \\##:id#"" />' 
            },
        // 4. Use a javascript function for value.       
            {
                title: "Test function",
                template: function(dataItem)    {
                    return "<strong>" 
                        + kendo.htmlEncode(dataItem.field3) 
                        + "</strong>";
                }
            }
        ],
        //==========================================
        // End of column fun.
        //==========================================

        filterable: true,
        sortable: true,
        pageable: true,
        height: 550,

        dataSource: {
            // http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.read
            transport: {
                read: {
                    url: "./GetInfo",
                    dataType: "json",
                    contentType: "application/json",
                    type:"POST"
                },
                parameterMap: function (data, type) {
                    // Removed this for now, but it's needed; see below.
                }
            },
            schema: {
                model: { id: "id" }
            },
            pageSize: 20,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
        },

        lastProp: null
    });
});

See, Telerik? Was that so hard? (They have so many examples this is probably in there somewhere, but it sure isn't where I'd expect it: At the top of columns.template explanation.


Just for fun, let's also return to the parameterMap function. The way Telerik grids send parameters for information requests is sort of strange. If you're pushing something up to a .NET MVC controller, you might not want stuff that looks like sort[0][field] before it's turned into a request. That's kind of hard to deserialize.

Instead, the answer is that you deserialize it yourself, on the client, in JavaScript, then reserialize into something easy to hand to your controller. I'm going to reorganize everything into a params object that I throw into a JSON string and return from parameterMap. My new string is what'll get passed back up.

parameterMap: function (data, type) {
    // By default, the grid sends a somewhat peculiar set of parameters with requests
    // that do server-side sorting. For example the sort { field: "age", dir: "desc" }
    // is sent (by default) as:
    //      sort[0][field]: age
    //      sort[0][dir]: desc
    // The parameterMap function allows us to send it up in a different format.
    // http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-sort
    var params = {
        skip: data.skip,
        take: data.take,
        page: data.page
    };

    if (data.sort)  {
        params.sort = {
            field: data.sort[0].field,
            dir: data.sort[0].dir
        };
    }
    // console.log wrapper >>> utils.logit("Param type: " + type);
    return JSON.stringify();
}

Kinda ugly default, but a reasonable way to customize things.

Labels: , ,