JSFiddle - React, Tailwind, and code Playground

by namuol

HTML

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
<script src="http://learn.knockoutjs.com/Scripts/Lib/jquery.tmpl.js"></script>
<script src="http://learn.knockoutjs.com/Scripts/Lib/jquery.address.js"></script>
<script src="http://learn.knockoutjs.com/Scripts/Lib/knockout-1.3.0.latest.js"></script>
<h2>Your clients (<span data-bind="text: seats().length"></span>)</h2>

<table>
    <thead><tr>
        <th>Last</th>
        <th>First</th>
        <th>Middle</th>
        <th>Will Date</th>
        <th>Updated</th>
        <th>With Affidavit</th>
        <th>Address</th>
        <th>City</th>
        <th></th>
    </tr></thead>
    <tbody data-bind="template: {name:'reservationTemplate', foreach: seats}"></tbody>
</table>

<script type="text/x-jquery-tmpl" id="reservationTemplate">
    <tr>
        <td><input data-bind="value: last" /></td>
        <td><input data-bind="value: first" /></td>
        <td><input data-bind="value: middle" /></td>
        <td><input data-bind="value: address" /></td>
        <td><input data-bind="value: city" /></td>
        <td><input data-bind="value: will_date" /></td>
        <td><input data-bind="value: will_updated" /></td>
        <td><input type='checkbox' data-bind="checked: affidivit"></input></td>
        <td data-bind="text: formattedPrice"></td>
        <td><a href="#" data-bind="click: remove">Remove</a></td>
    </tr>
</script>

<h3 data-bind="visible: totalSurcharge() > 0">
    Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>

<button data-bind="click: addSeat, enable: seats().length < 5">Reserve another seat</button>

JavaScript

// Raw catalog data - would come from the server
var availableMeals = [
    { mealName: "Standard (sandwich)", price: 0 },
    { mealName: "Premium (lobster)", price: 34.95 },
    { mealName: "Ultimate (whole zebra)", price: 290 }
];

// Class to represent a row in the reservations grid
var seatReservation = function(name) {
    this.name = name;
    this.availableMeals = availableMeals;
    this.meal = ko.observable(availableMeals[0]);

    this.formattedPrice = ko.dependentObservable(function() {
        var price = this.meal().price;
        return price ? "$" + price.toFixed(2) : "None";        
    }, this);

    this.remove = function() { viewModel.seats.remove(this) }
}

// Overall viewmodel for this screen, along with initial state
var viewModel = {
    seats: ko.observableArray([
        new seatReservation("Steve"),
        new seatReservation("Bert")
    ]),

    addSeat: function() {
        this.seats.push(new seatReservation());   
    }
};

viewModel.totalSurcharge = ko.dependentObservable(function() {
   var total = 0;
   for (var i = 0; i < this.seats().length; i++)
       total += this.seats()[i].meal().price;
   return total;
}, viewModel);

ko.applyBindings(viewModel);