JSFiddle - React, Tailwind, and code Playground
by aman1981
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.16/css/dataTables.bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.16/js/dataTables.bootstrap.min.js"></script>
<h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>
<table>
<thead>
<tr>
<th>Passenger Name</th>
<th>Meal</th>
<th>Amount ($)</th>
<th></th>
</tr>
</thead>
@*render a copy of seats child elements for each entry in the seats array*@
<tbody data-bind="foreach: seats">
<tr>
<td data-bind="text: name"></td>
@*update the view to make use of the formatted Price*@
<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">Remove</a></td>
</tr>
</tbody>
</table>
<button data-bind="click: addSeat, enable: seats().length < 3">Reserve Another Seat</button>
<h3 data-bind="visible: totalAmount() > 0">Total Amount: $<span data-bind="text: totalAmount().toFixed(2)"></span></h3>
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) : "None";
});
}
// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
var self = this;
// Non-editable Meals data - would come from the server
self.availableMeals = [
{ mealName: "Vegetarian Raw Meal", price: 10.52 },
{ mealName: "Vegetarian Vegan Meal", price: 34.95 },
{ mealName: "Fruit Platter Meal", price: 45.50 }
];
// Editable data - seats Array
self.seats = ko.observableArray([
new SeatReservation("Sampath", self.availableMeals[0]),
new SeatReservation("Lokuge", self.availableMeals[1])
]);
// Computed Total amount
self.totalAmount = ko.computed(function () {
var total = 0;
for (var i = 0; i < self.seats().length; i++)
total += self.seats()[i].meal().price;
return total;
});
// add seats
self.addSeat = function () {
self.seats.push(new SeatReservation("Chaminda", self.availableMeals[2]));
};
// remove seats
self.removeSeat = function (seat) { self.seats.remove(seat); };
}
ko.applyBindings(new ReservationsViewModel());