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

5

9

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.

Efficacy answered 28/2, 2015 at 16:34 Comment(0)
C
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)

Ctesiphon answered 28/2, 2015 at 18:8 Comment(2)
If the attributes property does not support functions, then this gets me as close as I am going to get.Efficacy
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)Droll
C
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>
Crabstick answered 28/2, 2015 at 17:2 Comment(1)
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.Efficacy
M
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)"
                }
Manipur answered 25/10, 2015 at 9:18 Comment(0)
O
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" });
})
Olympias answered 5/2, 2018 at 15:8 Comment(0)
H
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.

Hedonic answered 8/7, 2019 at 18:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.