<div id="content"></div> <div id="reservations"> <h2>Your seat reservations (<span id="count">0</span>)</h2> <input type="checkbox" name="editable"/> Edit Meals <ul id="meals"> <li> <input class="name" placeholder="Name" /> <input class="price" placeholder="Price" /> </li> </ul> <ul> <!-- additions: --> <li class="item"></li> <!-- /additions --> <li>Other</li> </ul> <table id="seats-table"> <thead> <tr> <th>Passenger name</th> <th>Meal</th> <th>Surcharge</th> <th>Additions</th> <th></th> </tr> </thead> <tbody id="seats"> <tr> <td><input class="name" /></td> <td><select class="meal test selected"></select></td> <td class="meal-formattedPrice"></td> <td><select class="additions"></select></td> <td class="list-additions"></td> <td><a href="#" class="removeSeat">Remove</a></td> </tr> </tbody> </table> <button id="addSeat">Reserve another seat</button> <h3 class="test showSurcharge"> Total surcharge: $<span id="totalSurcharge">0.00</span> </h3> </div>
var Meal = (function () { function Meal(name, price) { var _this = this; this.name = ko.observable(name).extend({ binding: "textInput" }); this.price = ko.observable(price || 0); this.formattedPrice = ko.computed(function () { return (_this.price() ? "$" + Number(_this.price.peek()).toFixed(2) : "None"); }, null, { deferEvaluation: true, pure: true }); } return Meal; }()); var Seat = (function () { function Seat(name, meal, additions) { var _this = this; this.name = name; this.meal = ko.observable(meal).extend({ bindings: "options:$root.meals,optionsText:'name'" }); this.additions = ko.observableArray(additions || []).extend({ bindings: "options:$root.additions,attr:{multiple:'multiple'}" }); this.selected = ko.utils.extend(function () { alert("You have selected: " + _this.meal.peek().name.peek()); }, { binding: "change" }); } return Seat; }()); var Reservations = (function () { function Reservations() { var _this = this; this.additions = ["Baggage", "Skis", "Wheelchair"]; this.meals = ko.utils.extend([ new Meal("Standard (sandwich)"), new Meal("Premium (lobster)", 34.95), new Meal("Ultimate (whole zebra)", 290) ], { bindings: "visible:editable" }); this.seats = ko.observableArray([ new Seat("Fred", this.meals[0]), new Seat("Bert", this.meals[1], this.additions.filter(function (item, index) { return index !== 1; })) ]).extend({ bindings: "attr:{title:'seats'}" }); this.editable = ko.observable(true); this.count = ko.computed(function () { return _this.seats().length; }); this.totalSurcharge = ko.computed(function () { return _this.seats().reduce(function (total, seat) { return (total + Number(seat.meal().price())); }, 0).toFixed(2); }); this.showSurcharge = ko.computed(function () { return _this.totalSurcharge() !== "0.00"; }); this.addSeat = ko.utils.extend(function () { _this.seats.push(new Seat("", _this.meals[0])); }, { bindings: "enable:seats().length<5" }); this.removeSeat = function (seat) { return _this.seats.remove(seat); }; } return Reservations; }()); var model = new Reservations(); ko.bindings = { "list-additions": { bindings: "text:additions" }, content: "template:'reservations'", "seats-table": "visible:count" }; ko.debug = true; ko.applyBindings(model, document.getElementById("content"));