learn.knockoutjs.com - Working with templates and lists
http://learn.knockoutjs.com/#/?tutorial=templates
HTML
<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>
<link rel="stylesheet" href="http://learn.knockoutjs.com/Content/App/coderunner.css">
<link rel="stylesheet" href="http://learn.knockoutjs.com/Content/TutorialSpecific/templates.css">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0rc2/jquery.mobile-1.0rc2.min.css">
<script src="http://code.jquery.com/mobile/1.0rc2/jquery.mobile-1.0rc2.min.js"></script>
<body>
<div data-role="page">
<div data-role="header">
<h1>
Tutorial 2
</h1>
</div>
<div data-role="content">
<div class="content-textbox">
Your seat reservations (<span data-bind="text: seats().length"></span>)
</div>
<div data-bind="template: {name:'reservationTemplate', foreach: seats, afterAdd: function() { $('.reservationItem').trigger('create') }}">
</div>
<script type="text/x-jquery-tmpl" id="reservationTemplate">
<div class="reservationItem">
<ul data-role="listview" data-inset=
"true">
<li data-role="list-divider">
Reservation
</li>
<li>
<div data-role="fieldcontain">
<label for="name">Name</label>
<input id="name" data-bind="value: name" />
</div>
<div data-role="fieldcontain">
<label for="meal">Meal</label>
<select id="meal" data-bind="options: availableMeals, value: meal, optionsText:...
CSS
.content-textbox {
background: none repeat scroll 0 0 #F9F9F9;
box-shadow: 0 0 3px #CCCCCC;
line-height: 1.2em;
margin-bottom: 15px;
margin-top: 10px;
padding: 8px;
}
JavaScript
(function() { // Wrap in function to prevent accidental globals
// 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);
})();