Skip to content

Instantly share code, notes, and snippets.

@blubbll
Last active May 22, 2020 10:35
Show Gist options
  • Save blubbll/e359a404e0cc9b419d11318282ed9bb2 to your computer and use it in GitHub Desktop.
Save blubbll/e359a404e0cc9b419d11318282ed9bb2 to your computer and use it in GitHub Desktop.
knockoutjs Tutorial 2
<h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>
<h3 data-bind="visible: totalSurcharge() > 0"> Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>
<style>
a[type=button],
button {
border: 2px solid black;
cursor: pointer;
padding: .125rem 1rem;
user-select: none;
border-radius: .3rem;
outline:0;
}
button[disabled]{
filter: none!important;
cursor: not-allowed;
}
a[type=button] {
background: darkred;
color: red;
}
a[type=button]:hover,
button:hover {
filter: brightness(1.4);
}
a[type=button]:active,
button:active {
filter: brightness(.6);
}
button {
</style>
<!--<button data-bind="click: addSeat, enable: seats().length < 5, text: 'Reserve another seat (' + (5 - seats().length)+ ' more available)'"></button>-->
<button data-bind="click: addSeat, enable: seats().length < 5, text: `Reserve another seat \t(${5 - seats().length} more available)`"></button>
<table>
<thead>
<tr>
<th>Passenger name</th>
<th>Meal</th>
<th>Surcharge</th>
<th>action</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 type="button" data-bind="click: $root.removeSeat">Remove</a></td>
</tr>
</tbody>
</table>
<script>
// 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(() => {
const 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 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([
new SeatReservation("Steve", self.availableMeals[0]),
new SeatReservation("Bert", self.availableMeals[0])
]);
//add
self.addSeat = () => self.seats.push(new SeatReservation("Robo", self.availableMeals[0]));
//delete
self.removeSeat = (seat) => self.seats.remove(seat);
//total
self.totalSurcharge = ko.computed(function() {
var total = 0;
for (var i = 0; i < self.seats().length; i++) total += self.seats()[i].meal().price;
return total;
});
}
ko.applyBindings(new ReservationsViewModel());
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment