Search code examples
javascriptkendo-uikendo-gridkendo-template

In a kendo grid, can I set column attributes dynamically with a function?


I've got some code here where I am trying to set a background color of a cell based on the value of the data item: http://dojo.telerik.com/@solidus-flux/eHaMu

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Kendo UI Snippet</title>

    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.common.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.rtl.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.default.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.dataviz.default.min.css">
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1411/styles/kendo.mobile.all.min.css">

    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://cdn.kendostatic.com/2014.3.1411/js/kendo.all.min.js"></script>
</head>
<body>

<div id="grid"></div>
<script>
$("#grid").kendoGrid({
  columns: [ {
    field: "name",
    title: "Name",
    attributes: function(e) {
      return {
        "class": "table-cell",
        style: e.name == "Jane Doe" ? "background-color: red" : "background-color: green"
      };
    }
    //attributes: {
      //"class": "table-cell",
      //style: "text-align: right; font-size: 14px"
    //}
  } ],
  dataSource: [ { name: "Jane Doe" }, { name: "John Doe" }]
});
</script>
</body>
</html>

I realize I could do this with a template, but that would require an extra html element, since you can't change the markup of the td itself. I'd like to use a function to return attributes if that is supported.


Solution

  • You said you don't want to use templates, but I think you were talking about column templates.

    You can change the markup of the td itself by using a row template:

    <script id="template" type="text/x-kendo-template">
        <tr data-uid="#= uid #">
          # this.columns.forEach(function(col) { 
              var val = data[col.field],
              css,
              style = ''
              cClasses = ''; 
              if (typeof col.attributes === 'function') {
                  css = col.attributes(data); 
                  cClasses = css["class"];
                  style = css.style
              } 
          #         
              <td class='#= cClasses #' style='#= style #'>
                #= data[col.field] #
              </td>
          # }) #
        </tr>
    </script>
    

    For the loop to work, you need to bind your template to the grid though:

    var grid = $("#grid").kendoGrid({
        columns: [{
            field: "name",
            title: "Name",
            attributes: function (e) {
                return {
                    "class": "table-cell",
                    style: e.name == "Jane Doe" ? 
                           "background-color: red" : "background-color: green"
                };
            }
        }, {
            field: "title",
            title: "Title"
        }],
        dataSource: [{name: "Jane Doe", title: "Dr. Dr."}, 
                     {name: "John Doe", title: "Senior Citizen"}]
    }).data("kendoGrid");
    
    var template = kendo.template($("#template").html()).bind(grid);
    grid.setOptions({
        rowTemplate: template
    });  
    

    (demo)

    As an alternative, you could also create attributes like this:

    {
        field: "name",
        title: "Name",
        attributes: { 
            "class": "# if(data.name === 'Jane Doe') { # red # } else { # green # } #" 
        }
    },
    

    This would have the advantage of not using the row template, but you'd have to use the template syntax for the logic.

    (demo)