Knockout Talk, Example 4
by Brian Dukes
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.1.0/knockout-min.js"></script>
<div id="wrap">
<h2 data-bind="text: title"></h2>
<ol data-bind="foreach: questions">
<li>
<label data-bind="attr: { for: 'q' + $index() }">
Question:
</label>
<input data-bind="value: title, attr: { id: 'q' + $index() }" />
</li>
</ol>
<ol data-bind="foreach: questions">
<li>
<label data-bind="text: title, attr: { for: 'eq' + $index() }"></label>
<!-- ko if: isText -->
<input data-bind="attr: { id: 'eq' + $index() }" />
<!-- /ko -->
<!-- ko if: isTextarea -->
<textarea data-bind="attr: { id: 'eq' + $index() }"></textarea>
<!-- /ko -->
<!-- ko if: isDropdown -->
<select data-bind="attr: { id: 'eq' + $index() }, options: answers"></select>
<!-- /ko -->
</li>
</ol>
</div>
JavaScript
/*globals ko */
var data = {
formId: 1,
title: 'Contact Form',
questions: [{
title: 'Name',
type: 'text'},
{
title: 'Reason',
type: 'dropdown',
answers: ['Sales', 'Support']},
{
title: 'Message',
type: 'textarea'}]
},
QuestionViewModel = function (question) {
var self = this;
self.title = ko.observable(question.title);
self.type = ko.observable(question.type);
self.answers = ko.observableArray(question.answers);
self.isText = ko.computed(function () { return self.type() === 'text'; });
self.isTextarea = ko.computed(function () { return self.type() === 'textarea'; });
self.isDropdown = ko.computed(function () { return self.type() === 'dropdown'; });
},
FormViewModel = function (form) {
var self = this,
questions = $.map(form.questions, function (q) { return new QuestionViewModel(q); });
self.formId = ko.observable(form.formId);
self.title = ko.observable(form.title);
self.questions = ko.observableArray(questions);
};
ko.applyBindings(new FormViewModel(data), document.getElementById('wrap'));