MVVM / Source and template binding

by dude_jsfiddle

HTML

<script src="http://cdn.kendostatic.com/2013.2.716/js/kendo.web.min.js"></script>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2013.2.716/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2013.1.514/styles/kendo.common.min.css">
<div id="example">
    <table>
        <thead>
            <tr>
                <th>IsSelected</th>
                <th>Name</th>
                <th>Price</th>
                <th>Units</th>
                <th>Delete</th>
            </tr>
        </thead>
        <tbody data-template="row-template" data-bind="source: products"></tbody>
    </table>

    <div>
        <span>Add a product</span>
        <ul>
            <li>
                <label>Name:<input type="text" placeholder="Enter name" data-bind="value: productName" /></label>
            </li>
            <li>
                <label>Price:<input type="number" placeholder="Enter number" data-bind="value: productPrice" /></label>
            </li>
            <li>
                <label>Units in stock:<input type="number" placeholder="Enter number" data-bind="value: productUnitsInStock" /></label>
            </li>
            <li>
                <button data-bind="click: addProduct">Add a new product</button>
            </li>
        </ul>
    </div>
</div>
<script id="row-template" type="text/x-kendo-template">
    <tr>
        <td><input type="checkbox" data-bind="checked: isSelected" />
        </td>
        <td data-bind="text: name">
        </td>
        <td>
            #: kendo.toString(get("price"), "C") #
        </td>
        <td data-bind="text: unitsInStock"></td>
        <td><button data-bind="click: deleteProduct">Delete</button></td>
    </tr>
</script>

JavaScript

var viewModel = kendo.observable({
    productName: "Product name",
    productPrice: 10,
    productUnitsInStock: 10,
    addProduct: function() {
        this.get("products").push({
            name: this.get("productName"),
            price: parseFloat(this.get("productPrice")),
            unitsInStock: parseFloat(this.get("productUnitsInStock"))
        });
    },
    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;
    },
    products: [
        { isSelected: false, name: "Hampton Sofa", price: 989.99, unitsInStock: 39 },
        { isSelected: true, name: "Perry Sofa", price: 559.99, unitsInStock: 17 },
        { isSelected: true, name: "Donovan Sofa", price: 719.99, unitsInStock: 29 },
        { isSelected: true, name: "Markus Sofa", price: 839.99, unitsInStock: 3 }
    ]
});

kendo.bind($("#example"), viewModel);