8

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.

Lars Höppner
  • 18,252
  • 2
  • 45
  • 73
Christopher
  • 10,409
  • 13
  • 73
  • 97

5 Answers5

14

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)

Lars Höppner
  • 18,252
  • 2
  • 45
  • 73
  • If the attributes property does not support functions, then this gets me as close as I am going to get. – Christopher Mar 01 '15 at 16:07
  • now that you say it, you can use functions in the attributes as long as you don't mind the template delimiters (and having to write it as a string) – Lars Höppner Mar 01 '15 at 17:01
0

Please try with the below code snippet.

<!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>
    <style>
        .greenBG {
            background-color:green;
        }
        .redBG {
            background-color:red;
        }
    </style>
</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"
                    };
                }
            }],
            dataSource: [{ name: "Jane Doe" }, { name: "John Doe" }],
            dataBound: function () {
                dataView = this.dataSource.view();
                for (var i = 0; i < dataView.length; i++) {
                    if (dataView[i].name === "Jane Doe") {
                        var uid = dataView[i].uid;
                        $("#grid tbody").find("tr[data-uid=" + uid + "]").addClass("greenBG");
                    }
                    else {
                        var uid = dataView[i].uid;
                        $("#grid tbody").find("tr[data-uid=" + uid + "]").addClass("redBG");
                    }
                }
            }
        });
    </script>
</body>
</html>
Jayesh Goyani
  • 11,008
  • 11
  • 30
  • 50
  • I got it working with something similar: `$("td").each(function () { if ($(this).text() === "Jane Doe") { $(this).addClass("good"); } });` but I was hoping not to have a loop. Just an attribute by function. – Christopher Feb 28 '15 at 17:11
0

In angular kendo callback e not work

Use this

attributes: {
                    "ng-confirm-message": "{{this.dataItem.is_active ? \'Are you sure deactive ?\' :  \'Are you sure active ?\'}}",
                    "confirmed-click": "vm.inlineSubmit(this.dataItem.toJSON() ,true)"
                }
Nishchit
  • 18,284
  • 12
  • 54
  • 81
0

For Kendo-JQuery.

<div id="grid"></div>
<script>
$("#grid").kendoGrid({
  columns: [{
    field: "name",
    headerAttributes: {
      "class": "table-header-cell",
      style: "text-align: right; font-size: 14px"
    }
  }]
});
</script>

And this Kendo-MVC

.Columns(columns =>
                {
                    columns.Bound(c => c.ActiveReason).Title("ActiveReason").HeaderHtmlAttributes(new { @class = "table-header-cell" });
})
MohammadSoori
  • 2,120
  • 1
  • 15
  • 17
0

Some years later but ... the attributes function is not working at all for me, is not even hit, seems pretty but not working (Why is needed a manual class toggle if a functions is provided to do the work? something seems weird).

I make editable cells based on other fields values but also I needed to change the styles

1) Add the validation on field that you want to inject the css class,

//Your other fields configuration
field:"dependentField",
attributes:
{
    "class": "# if(data.ImportantField!==true) { # nonEditableCellStyle # } else { # editableCellStyle # }# ",
}
//Your other fields configuration

2) Bind the grid change event and check if some important field has changes, if is the field that controls the style of other cells just call the refresh method

var _kendoGrid = $('#myGrid').data("kendoGrid");

_kendoGrid.dataSource.bind("change", function (e) {
    if (e.action === "itemchange") {
        if (e.field === "ImportantField") {
            _kendoGrid.refresh();
        }
    }
});

The refresh method will render your grid again, that means your functions weather is a template or an attribute function ( and again, that does not work at all for me) will run and apply the correct sytles, or classes in this case.