Kendo UI MVVM and the Grid: Example 03

Binding an editable Grid to a ViewModel with an editable calculated field.

HTML

<link rel="stylesheet" href="http://cdn.kendostatic.com/2012.2.710/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2012.2.710/styles/kendo.default.min.css">
<script src="http://cdn.kendostatic.com/2012.2.710/js/kendo.all.min.js"></script>
<div id="people">
    <div data-role="grid" 
         data-bind="source: people" 
         data-editable="false" 
         data-columns='[{ "field": "firstName", "title": "First Name" }, 
                        {"field": "lastName", "title": "Last Name"}, 
                        {"field": "lastUpdated", "title": "Full Name", "template": "#= fullName() #"}, 
                        { "field": "roleId", "title": "Role", "template": "#= parent().parent().getRoleName(roleId) #"}]'>
    </div>
</div>

JavaScript

var Person = kendo.data.Model.define({
    fields: {
        "firstName": {
            type: "string"
        },
        "lastName": {
            type: "string"
        },
        "roleId": {
            type: "number"                
        },
        "lastUpdated": {
            type: "date",
            editable: false
        }
    },
    fullName : function() {
        return this.get("firstName") + " " + this.get("lastName");
    }
});

// Define a DataSource
var peopleDataSource = new kendo.data.DataSource({
    data: [
        { id: 1, firstName: "John", lastName: "DeVight", roleId: 2 },
        { id: 2, firstName: "Wendy", lastName: "Parry", roleId: 1 }
    ],
    schema: {
        model: Person
    }
});

peopleDataSource.bind("change", function(e) {
    if (e.action === "itemchange") {
        if (e.field === "firstName" || e.field === "lastName") {
            e.items[0].dirty = true;
            kendo.data.ObservableObject.fn.set.call(e.items[0], "lastUpdated", new Date());
        }
    }
});

// Create an observable object.
var vm = kendo.observable({
    people: peopleDataSource,
    roles: [
        {
        id: 1,
        name: "CEO"},
    {
        id: 2,
        name: "Developer"},
    {
        id: 3,
        name: "Tester"}
    ],
    getRoleName: function(roleId) {
        var roleName = "";
        $.each(this.roles, function(idx, role) {
            if (role.id == roleId) {
                roleName = role.name;
                return false;
            }
        });
        return roleName;
    }
});

kendo.bind($("#people"), vm);

var roleEditor = function(container, options) {
    $("<input name='" + options.field + "'/>")
        .appendTo(container)
        .kendoDropDownList({
            dataSource: {
                data: vm.roles
            },
            dataTextField: "name",
            dataValueField: "id"
        });
};

var grid = $("div[data-role='grid']").data("kendoGrid");
$.each(grid.columns, function(idx, column)...