-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwizard.js
126 lines (110 loc) · 3.86 KB
/
wizard.js
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
define(['view',
'render',
'class'],
function(View, render, clazz) {
function Wizard(el, options) {
options = options || {};
Wizard.super_.call(this, el, options);
this._bodySel = options.bodySelector || '.body';
this._steps = [];
this._i = 0;
this._attachedTo = null;
var self = this
, el = this.el;
el.find('.prev').addClass('disabled');
el.find('.prev').on('click', function() {
if (el.find('.prev').hasClass('disabled')) return false;
self.prev(true);
return false;
});
if (options.form === false) {
// By default, `Wizard` expects to be attached to a form, and will advance
// to the next step on submit events. Set `form` option to `false` to
// override this behavior.
el.find('.next').on('click', function() {
if (el.find('.next').hasClass('disabled')) return false;
self.next(true);
return false;
});
}
}
clazz.inherits(Wizard, View);
Wizard.prototype.remove = function() {
return Wizard.super_.prototype.remove.call(this);
}
Wizard.prototype.attach = function(id) {
if (this._attachedTo) return;
this._attachedTo = id;
var self = this
, el = this.el;
render.$(id).on('submit', function(e) {
if (el.find('.next').hasClass('disabled')) return false;
self.next(true);
return false;
})
}
Wizard.prototype.step = function(name, el, options) {
if (typeof name != 'string') {
options = el;
el = name;
name = undefined;
}
options = options || {};
options.prevable = options.prevable !== undefined ? options.prevable : true;
options.nextable = options.nextable !== undefined ? options.nextable : true;
if (this._steps.length) el.addClass('hide');
this.el.find(this._bodySel).append(el);
this._steps.push({ el: el, name: name, opts: options });
return this;
};
Wizard.prototype.next = function(ask) {
if (this._i >= this._steps.length) throw new Error('index out of range');
var step = this._steps[this._i]
, fin = this._i == this._steps.length - 1 ? true : step.opts.final;
if (fin) { this.emit('done', step.name, this._i); return; }
var go = (ask && this.delegate && this.delegate.willNext) ? this.delegate.willNext(step.name, this._i) : true;
if (go) this._goto(this._i + 1, this._i);
}
Wizard.prototype.prev = function(ask) {
if (this._i == 0) return;
var step = this._steps[this._i];
var go = (ask && this.delegate && this.delegate.willPrev) ? this.delegate.willPrev(step.name, this._i) : true;
if (go === false) {
return;
} else if (go === true) {
go = this._i - 1;
} else if (typeof go == 'string') {
for (var i = 0, len = this._steps.length; i < len; i++) {
if (this._steps[i].name == go) { go = i; break; }
}
}
this._goto(go, this._i);
}
Wizard.prototype.to = function(step) {
var i;
if (typeof step == 'number') {
i = step;
} else if (typeof step == 'string') {
for (var ix = 0, len = this._steps.length; ix < len; ix++) {
if (this._steps[ix].name == step) { i = ix; break; }
}
}
if (i == undefined) throw new Error('invalid argument');
this._goto(i, this._i);
}
Wizard.prototype._goto = function(i, pi) {
this._i = i;
var step = this._steps[i]
, prevable = i == 0 ? false : step.opts.prevable
, nextable = step.opts.nextable;
this.emit('step', step.name, i);
this._steps[pi].el.addClass('hide');
this._steps[i].el.removeClass('hide');
if (prevable) this.el.find('.prev').removeClass('disabled');
else this.el.find('.prev').addClass('disabled');
if (nextable) this.el.find('.next').removeClass('disabled');
else this.el.find('.next').addClass('disabled');
this.emit('stepped', step.name, i);
}
return Wizard;
});