How to bind a Knockout js model to a wizard style UI

http://stackoverflow.com/questions/7428677/how-to-bind-a-knockout-js-model-to-a-wizard-style-ui

HTML

<script src="http://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<div data-bind="template: { name: 'currentTmpl', data: currentStep }"></div> 

<hr/>

<button data-bind="click: goPrevious, enable: canGoPrevious">Previous</button>
<button data-bind="click: goNext, enable: canGoNext">Next</button>

<script id="currentTmpl" type="text/html">
    <h2 data-bind="text: name"></h2>
    <div data-bind="template: { name: getTemplate, data: model }"></div> 
</script>

<script id="basicTmpl" type="text/html">
    <div data-bind="text: message"></div>
</script>

<script id="choiceTmpl" type="text/html">
    <input type="checkbox" data-bind="checked: choiceOne" /> Choice One <br/>
    <input type="checkbox" data-bind="checked: choiceTwo" /> Choice Two
</script>

<script id="confirmTmpl" type="text/html">
    <button data-bind="click: confirm">Confirm</button>
</script>

JavaScript

function Step(id, name, template, model) {
   var self = this;
   self.id = id;
   self.name = ko.observable(name);
   self.template = template;
   self.model = ko.observable(model);  
    
   self.getTemplate = function() {
       return self.template;   
   }
}

function ViewModel() {
    var self = this;
    self.stepModels = ko.observableArray([
         new Step(1, "Welcome", "basicTmpl", { message: "hello and welcome!" }),
        new Step(2, "Choices", "choiceTmpl", { choiceOne: ko.observable(false), choiceTwo: ko.observable(false) }),
        new Step(3, "Confirmation", "confirmTmpl", { confirm: function() {self.currentStep(self.stepModels()[3]); } } ),
         new Step(4, "Congratulations!", "basicTmpl", { message: "you are finished!" })
    ]);
    
    self.currentStep = ko.observable(self.stepModels()[0]);
    
    self.currentIndex = ko.dependentObservable(function() {
        return self.stepModels.indexOf(self.currentStep());    
    });

    self.getTemplate = function(data) {
         return self.currentStep().template();   
    };
:
    self.canGoNext = ko.dependentObservable(function() {
        return self.currentIndex() < self.stepModels().length - 1;
    });

    self.goNext = function() {
        if (self.canGoNext()) {
             self.currentStep(self.stepModels()[self.currentIndex() + 1]);   
        }
    };
             
    self.canGoPrevious = ko.dependentObservable(function() {
        return self.currentIndex() > 0;
    });

    self.goPrevious = function() {
        if (self.canGoPrevious()) {
             self.currentStep(self.stepModels()[self.currentIndex() - 1]);   
        }   
    };
};

ko.applyBindings(new ViewModel());