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'));