JSFiddle - React, Tailwind, and code Playground

by amorris

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.1.7/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js"></script>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap-1.1.1.min.css">
<script src="https://raw.github.com/derickbailey/backbone.modelbinding/master/backbone.modelbinding.js"></script>
<script type="text/template" id="product-default-template">
    <td class="title"><%= title %></td>
    <td><input class="qty" id="qty" type="text" maxlength="3" value="<%= qty %>"></td>
    <td class="cost-price"><%= costPrice %></td>
    <td class="cost-price-total"><%= costPriceTotal %></td>
    <td>
      <input class="sell-price price" id="sellPrice" type="text" maxlength="6" value="<%= sellPrice %>">
    </td>
    <td class="sell-price-total" data-bind="text sellPriceTotal"><%= sellPriceTotal %></td>
</script>

<p>
    <table>
        <thead>
            <tr>
                <th>Title</th>
                <th>Qty</th>
                <th>Price</th>
                <th>Price total</th>
                <th>Sell price</th>
                <th>Sell price total</th>
            </tr>
        </thead>
        <tbody>
            <tr id="product">
            </tr>
        </tbody>
    </table>
</p>

CSS

input[type="text"].qty, input[type="text"].price { width: 40px }

JavaScript

var Product = Backbone.Model.extend({
    defaults: {
        title: "Title",
        costPrice: 0,
        sellPrice: 0,
        costPriceTotal: 0,
        sellPriceTotal: 0,
        qty: 0
    },
    summarize: function() {
        var _costPriceTotal = this.get('qty') * this.get('costPrice');
        var _sellPriceTotal = this.get('qty') * this.get('sellPrice');
        
        this.set({
            costPriceTotal: _costPriceTotal,
            sellPriceTotal: _sellPriceTotal
        });
    }
});

var ProductView = Backbone.View.extend({
    el: $('#product'),
    template: _.template($('#product-default-template').html()),
    events: {
        'keypress .qty':  'input',
        'keyup .qty':  'input',
        'keypress .price':  'input',
        'keyup .price':  'input'
    },
    initialize: function() {
        _.bindAll(this, 'render', 'input');        
        this.render();
    },
    render: function() {
        $(this.el).html(this.template( this.model.toJSON() ) );
      
        Backbone.ModelBinding.bind(this);
        return this;
    },
    input: function(e) {
        if(e.type == 'keypress' && !(e.charCode >= 48 && e.charCode <= 57)) {
            e.preventDefault();
            return;
        }
        
        if(e.type == 'keyup') {
            if(e.which >= 48 && e.which <= 57) {
                var ct = $(e.currentTarget);
                var _qty = parseInt( ct.val() );
                
                this.model.set({qty: _qty});
                this.model.summarize();
            }
        }
    }
});

var prodView = new ProductView({ model: new Product({title: 'my product', costPrice: 150, sellPrice: 300}) });