kendo table - Source and template binding

Sample from web/demo/mvvm http://demos.kendoui.com/web/mvvm/source.html

by jwstott

HTML

<link rel="stylesheet" href="http://cdn.kendostatic.com/2012.1.322/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2012.1.322/styles/kendo.default.min.css">
<script src="http://cdn.kendostatic.com/2012.1.322/js/kendo.all.min.js"></script>
<div id="example" class="k-content">
    <div class="demo-section">
        <table id="products" class="metrotable">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Price</th>
                    <th>Units</th>
                    <th>Checked</th>
                    <th>Delete</th>
                </tr>
            </thead>
            <tbody data-template="row-template" data-bind="source: products">
            </tbody>
            <tfoot data-template="footer-template" data-bind="source: this">
            </tfoot>
        </table>
        
    </div>

    <script id="row-template" type="text/x-kendo-template">
        <tr>
            <td data-bind="text: name">
            </td>
            <td>
                #: kendo.toString(get("price"), "C") #
            </td>
            <td data-bind="text: unitsInStock"></td>
            <td> <input type='checkbox' data-bind="checked: oem"/>
            <td><button class="k-button" data-bind="click: deleteProduct">Delete</button></td>
        </tr>
    </script>
    <script id="footer-template" type="text/x-kendo-template">
        <tr>
            <td>
                Products count: #: total() #
            </td>
            <td>
                Total price: #: totalPrice() #
            </td>
            <td colspan="2">
                Units in stock: #: totalUnitsInStock() #
            </td>
            
        </tr>
    </script>

CSS

.demo-section {
            width: 600px;
            min-height: 200px;
        }
        .metrotable > tbody > tr > td  {
            font-size: 12px;
        }
        .metrotable > thead > tr > th {
            font-size: 14px;
            padding-top: 0;
        }
        
        .metrotable > tfoot > tr > td {
            padding-right: 10px;
        }
        
        #example .configuration {
            margin-bottom: 10px;
            width: 190px;
        }

        .configuration label {
            display: block;
            float: none;
        }

        .configuration .name {
            margin-top: -3px;
            width: 130px;
        }
        .code-sample {
            clear: right;
        }

JavaScript

var viewModel = kendo.observable({
    productName: "Product name",
    productPrice: 10,
    productUnitsInStock: 10,
    addProduct: function(obj) {
        this.get("products").push(obj);
    },
    deleteProduct: function(e) {
        // the current data item (product) is passed as the "data" field of the event argument
        var product = e.data;

        var products = this.get("products");

        var index = products.indexOf(product);

        // remove the product by using the splice method
        products.splice(index, 1);
    },
    total: function() {
        return this.get("products").length;
    },
    totalPrice: function() {
        var sum = 0;

        $.each(this.get("products"), function(index, product) {
            sum += product.price;
        });

        return sum;
    },
    totalUnitsInStock: function() {
        var sum = 0;

        $.each(this.get("products"), function(index, product) {
            sum += product.unitsInStock;
        });

        return sum;
    },
    watch: function() {
        //var prod = this.get('products');
        this.products.bind("change", function(e) {
            // e.data.set('unitsInStock',100);
            console.log(e.action, e.field);
        });
    },
    totalOEM: 5,
    products: [],
    isDirty: function() {
        //var vm = this;
        var prod = this.get('products');
        prod.bind("change", function(e) {
            // e.data.set('unitsInStock',100);
            console.log(e.action, e.field);
            return true;
        });
        return false;
    }

});
viewModel.addProduct({
    name: "Hampton Sofa",
    price: 989.99,
    unitsInStock: 39,
    oem: false
});
viewModel.addProduct({
    name: "Perry Sofa",
    price: 559.99,
    unitsInStock: 17,
    oem: false
});
viewModel.addProduct({
    name: "Donovan Sofa",
    price: 719.99,
    unitsInStock: 29,
    oem: true
});
viewModel.addProduct({
    name: "Markus Sofa",
    price: 839.99,
    unitsInStock: 3,
    oem:...