Knockout.JS Tutorials
Reserva de Asientos
by Marventus
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<h2>Reserva de Asientos (<span data-bind="text: seats().length"></span>)</h2>
<table class="table">
<thead><tr>
<th>Nombre del<br/>pasajero</th>
<th>Comida</th>
<th>Recargo</th>
<th></th>
</tr></thead>
<tbody data-bind="foreach: seats">
<tr>
<td><input data-bind="value: name" /></td>
<td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
<td data-bind="text: formattedPrice"></td>
<td><a href="#" data-bind="click: $root.removeSeat">Eliminar</a></td>
</tr>
</tbody>
</table>
<button data-bind="click: addSeat, enable: seatLimit() < 5" class="btn btn-primary">Reserve otro asiento</button>
<h3 data-bind="visible: totalSurcharge() > 0">
Recargo total: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>
CSS
table {
width: 100%;
}
table td,
table th{
padding: 5px;
text-align:center;
}
h2 span {
color:#337ab7;
}
JavaScript
// Class to represent a row in the seat reservations grid
function SeatReservation(name, initialMeal) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
self.formattedPrice = ko.computed(function() {
var price = self.meal().price;
return "$ " + ( price ? price.toFixed(2) : "0" );
});
}
// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
var self = this;
self.viewers = ["Steve", "Bert", "John"];
// Non-editable catalog data - would come from the server
self.availableMeals = [
{ mealName: "Standard (sandwich)", price: 0 },
{ mealName: "Premium (lobster)", price: 34.95 },
{ mealName: "Ultimate (whole zebra)", price: 290 }
];
// Editable data
self.seats = ko.observableArray();
for(i=0; i<self.viewers.length; i++) {
self.seats.push( new SeatReservation(self.viewers[i], self.availableMeals[0]) );
}
// Operations
self.addSeat = function() {
self.seats.push(new SeatReservation("", self.availableMeals[0]));
}
self.removeSeat = function(seat) {
self.seats.remove(seat);
}
self.totalSurcharge = ko.computed(function() {
var t = 0;
for (var i = 0; i < self.seats().length; i++)
t += self.seats()[i].meal().price;
console.log(self.seats());
return t;
});
self.seatLimit = function() {
var block = self.seats().length >= 5 ? true : false,
msg = "Ha excedido el número máximo de asientos (5) que puede reservar.";
if( block )
alert(msg);
return self.seats().length;
}
}
ko.applyBindings(new ReservationsViewModel());