Here I am going to demonstrate a simple (emphasis on simple) single-page application, using knockoutjs. For more information on knockoutjs visit their official website.
This demo site I will be going through is for requesting conference tickets and is written as an ASP.Net MVC (Razor) application. The layout page contains the script references to jquery, bootstrap and knockoutjs and contains the template header, menu and footer sections. I will not be going through the implementation of these libraries or layout page in detail.
The ticket request site has three views
1. Introduction (intro)

2. Ticket Request Form (requestform)

3. Ticket Request Confirmation (confirmation)

There are limitations
- The request form does not contain any validation.
- The request does not actually get sent anywhere.
First of we’ll look at the script.
<script type="text/javascript" language="javascript">
var model = {
view: ko.observable("intro"),
request: {
name: ko.observable(""),
email: ko.observable(""),
phone: ko.observable(""),
quantity: ko.observable(0)
},
}
var showForm = function () {
model.view("requestform");
}
var sendRequest = function () {
model.view("confirmation")
}
var showIntro = function () {
model.view("intro")
}
$(document).ready(function () {
ko.applyBindings();
})
</script>
The viewmodel has two properties, the view property is an observable string containing the the name of the current view being displayed. The request property is an object that hold the details of the request and contains the following observable properties name, email, phone and quantity.
There are three methods named showIntro, showForm and sendRequest. These methods are called when
clicking the navigation buttons at the bottom of the views. Each method will set the observable view property of the viewmodel to the respective view name.
The model is bound to the page using the ko.applyBindings() call when the page has finished loading.
Now let’s look at the html code.
All the views are wrapped in a single form element. Each view is contained in a separate DIV element. On each view notice how the visibility of the outer DIV is controlled by a condition comparing the view name with the view property of the viewmodel.
The introduction holds instructions for completing the request. This view will only be visible when the viewmodel view property is set to ‘intro’.
<div data-bind="visible: model.view() == 'intro'">
<div class="panel panel-success">
<div class="panel-heading"><h4>Conference Tickets</h4></div>
<div class="panel-body">
<div class="text-justify">
<p>
This is a demonstration of a simple single-page application using Knockoutjs.
</p>
<strong>There are three sections</strong>
<ul class="list-unstyled">
<li><span class="glyphicon glyphicon-info-sign"></span> Introduction (This page)</li>
<li><span class="glyphicon glyphicon-tasks"></span> Request Form</li>
<li><span class="glyphicon glyphicon-ok"></span> Thank you/Confirmation</li>
</ul>
<strong>Notes:</strong>
<ul class="list-unstyled">
<li><span class="glyphicon glyphicon-asterisk"></span>There is no validation on form fields or on form submission.</li>
<li><span class="glyphicon glyphicon-asterisk"></span>This is a coding example only, the request is not actually sent anywhere.</li>
<li><span class="glyphicon glyphicon-asterisk"></span>No personal information is collected or sent.</li>
</ul>
</div>
<div class="text-center">
<button class="btn btn-success" data-bind="click: showForm">Next</button>
</div>
</div>
</div>
</div>
The request form gathers information relating to the conference ticket request. This view will only be visible when the viewmodel view property is set to ‘requestform’.
<div data-bind="visible: model.view() == 'requestform'">
<div class="panel panel-success">
<div class="panel-heading"><h4>Conference Tickets</h4></div>
<div class="panel-body">
<div class="col-xs-4">
<div class="form-group">
<label>Full name:</label>
<input type="text" class="form-control" data-bind="value: model.request.name" />
</div>
<div class="form-group">
<label>Contact email:</label>
<input class="form-control" data-bind="value: model.request.email" required />
</div>
<div class="form-group">
<label>Contact phone:</label>
<input class="form-control" data-bind="value: model.request.phone" />
</div>
<div class="form-group">
<label>How many will attend?</label>
<select class="form-control" data-bind="value: model.request.quantity">
<option value="0">Not Attending</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
</div>
<div class="col-xs-12 text-center">
<button class="btn btn-success" data-bind="click: showIntro"> Back </button>
<button class="btn btn-success" data-bind="click: sendRequest"> Submit Request </button>
</div>
</div>
</div>
</div>
Finally, the confirmation view displays a summary of the request. This view will only be visible when the viewmodel view property is set to ‘confirmation’.
<div data-bind="visible: model.view() == 'confirmation'">
<h1>
<span data-bind="visible: model.request.quantity() == '0'">
Oh no! <span data-bind="text: model.request.name()"></span>, I'm gutted you're not coming.
</span>
<span data-bind="visible: model.request.quantity() != '0'">
Yay! <span data-bind="text: model.request.name()"></span> is coming.
</span>
</h1>
<div class="lead">
<strong>Here are the details submitted</strong>
Contact phone: <span data-bind="text: model.request.email()"></span>
Contact email: <span data-bind="text: model.request.phone()"></span>
No of tickets: <span data-bind="text: model.request.quantity()"></span>
</div>
<div class="text-center">
<button class="btn btn-success" data-bind="click: showForm">Back</button>
</div>
</div>
As I often say, this is not the only way but it is effective. There can be as many views as are required.
You must be logged in to post a comment.