JSFiddle - React, Tailwind, and code Playground

by fourFath3r

HTML

<script src="http://knockoutjs.com/js/jquery.tmpl.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.2.1.js"></script>
    <table class="products">
        <thead>
            <tr>
                <th>
                    Produkt
                </th>
                <th>
                    Pris
                </th>
                <th>
                    Antal/enhet
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody id="productlist" data-bind='template: {name: "productTemplate",
                                                      foreach: itemsInStock}'>
        </tbody>
    </table>
    <table class="cart">
        <thead>
            <tr>
                <th>
                    Produkt
                </th>
                <th>
                    Antal
                </th>
                <th>Pris</th>
                <th></th>
            </tr>
        </thead>
        <tbody id="shoppingcart" data-bind='template: {name: "cartTemplate",
                                                      foreach: itemsInCart}'>
        </tbody>
        <tfoot>
            <tr>
                <td>Total price:</td><td></td><td data-bind="text: totalPrice"></td><td></td>
            </tr>
        </tfoot>
    </table>
    <script id="productTemplate" type='text/html'>
       
            <tr>
                <td>${ProductName}</td>
                <td>${UnitPrice}</td>
                <td>${Stock}</td>
                <td><input type="button" value="Add" data-bind="click: function(){ cartViewModel.addProduct($data) }"/>
            </tr> 
   
    </script>
    <script id="cartTemplate" type='text/html'>
       
            <tr>
                <td>${productname}</td>
                <td>${quantity}</td>
                <td>${price}</td>
                <td><input type="button" value="Remove" data-bind="click: function(){ cartViewModel.removeProduct($data) }"/>
            </tr>...

CSS

.products{float:left;width:50%}
thead th {
border-bottom:1px solid #333;
border-left:1px solid #333;
text-align:center;
font:bold 1.2em/2em "Century Gothic","Trebuchet MS",Arial,Helvetica,sans-serif;
color:#000;
}

table{width:50%
border-top:1px solid #333;
border-right:1px solid #333;

}
td{
color:#678197;
border-bottom:1px solid #333;
border-left:1px solid #333;
text-align:center;
padding:4px
}
.cart{width:50%;float:right}
input{padding:4px}

JavaScript

var cartViewModel = {
    itemsInStock: ko.observableArray([]),
    itemsInCart: ko.observableArray([]),
    addProduct: function(product) {
        this.itemsInCart.push({
            productname: product.ProductName,
            quantity: 1,
            price: product.UnitPrice
        });

    },
    removeProduct: function(product) {
        this.itemsInCart.remove(product);
    }

};

cartViewModel.totalPrice = ko.dependentObservable(function () {
    var total = 0;

    ko.utils.arrayForEach(this.itemsInCart(), function (product) {
        var value = product.price;
        if (!isNaN(value)) {
            total += value;
        }
    });
    return total.toFixed(2);
}, cartViewModel);

ko.applyBindings(cartViewModel);
cartViewModel.itemsInStock([{
    "ProductName": "Chai",
    "UnitPrice": 18,
    "Stock": "10 boxes x 20 bags"},
{
    "ProductName": "Chang",
    "UnitPrice": 19,
    "Stock": "24 - 12 oz bottles"},
{
    "ProductName": "Aniseed Syrup",
    "UnitPrice": 10,
    "Stock": "12 - 550 ml bottles"},
{
    "ProductName": "Chef Anton\u0027s Cajun Seasoning",
    "UnitPrice": 22,
    "Stock": "48 - 6 oz jars"}
                                                                                                                              ]);