Backbone.js Wizard

  • Download Gist
backbone view that calls the wizard ui element
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
namespace.views.MyWizard = Backbone.Views.extend({
 
initialize: function() {
_.bindAll(this, 'render', 'wizardMethod');
}
 
render: function() {
this.wizardMethod();
return this;
},
 
wizardMethod: function() {
var myModel = new MyModel;
var steps = [
{
step_number : 1,
title : "Title of Step 1",
instructions : "Instructions or description of what the user needs to do for this step",
view : new namespace.views.WizardStepOne({ model : myModel })
},
{
step_number : 2,
title : "Title of Step 2",
instructions : "Instructions or description of what the user needs to do for this step",
view : new namespace.views.WizardStepTwo({ model : myModel })
},
{
step_number : 3,
title : "Title of Step 3",
instructions : "Instructions or description of what the user needs to do for this step",
view : new namespace.views.WizardStepThree({ model : myModel })
}
];
var view = new nameplace.ui.Wizard({
model : myModel,
steps : steps
});
$("#current_step").html(view.render().el);
}
});
wizard.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
namespace.ui.Wizard = Backbone.View.extend({
id: 'wizard',
 
events: {
"click #next_step_button" : "nextStep",
"click #prev_step_button" : "prevStep"
},
initialize: function() {
_.bindAll(this, 'render');
this.currentStep = 0;
},
 
render: function() {
var t = template('ui/wizard');
$(this.el).html( t({}) );
this.progressIndicator = this.$("#progress_indicator");
this.title = this.$("h2#step_title");
this.instructions = this.$("p#step_instructions");
this.currentStepContainer = this.$(".current_step_container");
this.nextStepButton = this.$("#next_step_button");
this.prevStepButton = this.$("#prev_step_button");
this.renderCurrentStep();
return this;
},
renderProgressIndicator: function() {
this.progressIndicator.empty();
_.each(this.options.steps, _.bind(function(step) {
var text = "(" + step.step_number + ") " + step.title + ">>> ";
var el = this.make('span', {}, text);
if (step.step_number == this.currentStep + 1) $(el).addClass('active');
this.progressIndicator.append(el);
}, this));
},
renderCurrentStep: function() {
var currentStep = this.options.steps[this.currentStep];
if (!this.isFirstStep()) var prevStep = this.options.steps[this.currentStep - 1];
var nextStep = this.options.steps[this.currentStep + 1];
 
this.title.html(currentStep.title);
this.instructions.html(currentStep.instructions);
this.currentView = currentStep.view;
this.currentStepContainer.html(this.currentView.render().el);
 
this.renderProgressIndicator();
if (prevStep) {
this.prevStepButton.html("Prev: " + prevStep.title).show()
} else {
this.prevStepButton.hide();
};
if (nextStep) {
this.nextStepButton.html("Next: " + nextStep.title);
} else {
this.nextStepButton.html("Finish");
};
},
nextStep: function() {
if (this.currentView.validate()) {
if (!this.isLastStep()) {
this.currentView.validate();
this.currentStep += 1;
this.renderCurrentStep();
} else {
this.save();
};
};
},
prevStep: function() {
if (!this.isFirstStep()) {
this.currentStep -= 1;
this.renderCurrentStep();
};
},
isFirstStep: function() {
return (this.currentStep == 0);
},
isLastStep: function() {
return (this.currentStep == this.options.steps.length - 1);
}
});
wizard.jst
1 2 3 4 5 6 7 8 9 10 11 12
<header>
<div id="progress_indicator"></div>
<h2 id="step_title"></h2>
<p id="step_instructions"></p>
</header>
<div class="current_step_container"></div>
<footer>
<div id="buttons">
<a id="prev_step_button" class="button">Prev:</a>
<a id="next_step_button" class="button">Next:</a>
</div>
</footer>

Very easy to understand. I do have 1 question. Is their any special meaning to line #3 in wizard.js: id: 'wizard',?
I guess what I'm asking is do I have to have a div id='wizard' in the mark-up that this needs to match? I havent seen id used/set much at all.

You've included this.currentView.validate() within namespace.ui.Wizard.nextStep, however .validate() is not a method of Backbone.View. Have you purposely left this as an exercise for the reader? Or perhaps you meant this.currentView.model.validate()?

I am a beginner in backbone js. Can I please get a tutorial on this since I am finding it a bit difficult using this wizard in my own app.

@somethingkindawierd Presumably view.validate() is a custom method that only validates the data on that page (since validating the whole model would fail until you get to the end). It's too bad this gist doesn't include the views.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.