public.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. $.extend(Wizard.prototype, {
  2. Constructor: Wizard,
  3. initialize: function(){
  4. this.steps = [];
  5. var self = this;
  6. this.$steps.each(function(index){
  7. self.steps.push(new Step(this, self, index));
  8. });
  9. this._current = 0;
  10. this.transitioning = null;
  11. $.each(this.steps, function(i, step){
  12. step.setup();
  13. });
  14. this.setup();
  15. this.$element.on('click', this.options.step, function(e){
  16. var index = $(this).data('wizard-index');
  17. if(!self.get(index).is('disabled')){
  18. self.goTo(index);
  19. }
  20. e.preventDefault();
  21. e.stopPropagation();
  22. });
  23. if(this.options.keyboard){
  24. $(document).on('keyup', $.proxy(this.keydown, this));
  25. }
  26. this.trigger('init');
  27. },
  28. setup: function(){
  29. this.$buttons = $(this.options.templates.buttons.call(this));
  30. this.updateButtons();
  31. var buttonsAppendTo = this.options.buttonsAppendTo;
  32. var $to;
  33. if(buttonsAppendTo ==='this'){
  34. $to = this.$element;
  35. } else if($.isFunction(buttonsAppendTo)){
  36. $to = buttonsAppendTo.call(this);
  37. } else {
  38. $to = this.$element.find(buttonsAppendTo);
  39. }
  40. this.$buttons = this.$buttons.appendTo($to);
  41. },
  42. updateButtons: function(){
  43. var classes = this.options.classes.button;
  44. var $back = this.$buttons.find('[data-wizard="back"]');
  45. var $next = this.$buttons.find('[data-wizard="next"]');
  46. var $finish = this.$buttons.find('[data-wizard="finish"]');
  47. if(this._current === 0){
  48. $back.addClass(classes.disabled);
  49. } else {
  50. $back.removeClass(classes.disabled);
  51. }
  52. if(this._current === this.lastIndex()) {
  53. $next.addClass(classes.hide);
  54. $finish.removeClass(classes.hide);
  55. } else {
  56. $next.removeClass(classes.hide);
  57. $finish.addClass(classes.hide);
  58. }
  59. },
  60. updateSteps: function(){
  61. var self = this;
  62. $.each(this.steps, function(i, step){
  63. if(i > self._current){
  64. step.leave('error');
  65. step.leave('active');
  66. step.leave('done');
  67. if(!self.options.enableWhenVisited ){
  68. step.enter('disabled');
  69. }
  70. }
  71. });
  72. },
  73. keydown: function(e) {
  74. if (/input|textarea/i.test(e.target.tagName)) return;
  75. switch (e.which) {
  76. case 37: this.back(); break;
  77. case 39: this.next(); break;
  78. default: return;
  79. }
  80. e.preventDefault();
  81. },
  82. trigger: function(eventType){
  83. var method_arguments = Array.prototype.slice.call(arguments, 1);
  84. var data = [this].concat(method_arguments);
  85. this.$element.trigger('wizard::' + eventType, data);
  86. // callback
  87. eventType = eventType.replace(/\b\w+\b/g, function(word) {
  88. return word.substring(0, 1).toUpperCase() + word.substring(1);
  89. });
  90. var onFunction = 'on' + eventType;
  91. if (typeof this.options[onFunction] === 'function') {
  92. this.options[onFunction].apply(this, method_arguments);
  93. }
  94. },
  95. get: function(index) {
  96. if(typeof index === 'string' && index.substring(0, 1) === '#'){
  97. var id = index.substring(1);
  98. for(var i in this.steps){
  99. if(this.steps[i].$pane.attr('id') === id){
  100. return this.steps[i];
  101. }
  102. }
  103. }
  104. if(index < this.length() && this.steps[index]){
  105. return this.steps[index];
  106. }
  107. return null;
  108. },
  109. goTo: function(index, callback) {
  110. if(index === this._current || this.transitioning === true){
  111. return false;
  112. }
  113. var current = this.current();
  114. var to = this.get(index);
  115. if(index > this._current){
  116. if(!current.validate()){
  117. current.leave('done');
  118. current.enter('error');
  119. return -1;
  120. } else {
  121. current.leave('error');
  122. if(index > this._current) {
  123. current.enter('done');
  124. }
  125. }
  126. }
  127. var self = this;
  128. var process = function (){
  129. self.trigger('beforeChange', current, to);
  130. self.transitioning = true;
  131. current.hide();
  132. to.show(function(){
  133. self._current = index;
  134. self.transitioning = false;
  135. this.leave('disabled');
  136. self.updateButtons();
  137. self.updateSteps();
  138. if(self.options.autoFocus){
  139. var $input = this.$pane.find(':input');
  140. if($input.length > 0) {
  141. $input.eq(0).focus();
  142. } else {
  143. this.$pane.focus();
  144. }
  145. }
  146. if($.isFunction(callback)){
  147. callback.call(self);
  148. }
  149. self.trigger('afterChange', current, to);
  150. });
  151. };
  152. if(to.loader){
  153. to.load(function(){
  154. process();
  155. });
  156. } else {
  157. process();
  158. }
  159. return true;
  160. },
  161. length: function() {
  162. return this.steps.length;
  163. },
  164. current: function() {
  165. return this.get(this._current);
  166. },
  167. currentIndex: function() {
  168. return this._current;
  169. },
  170. lastIndex: function(){
  171. return this.length() - 1;
  172. },
  173. next: function() {
  174. if(this._current < this.lastIndex()){
  175. var from = this._current, to = this._current + 1;
  176. this.goTo(to, function(){
  177. this.trigger('next', this.get(from), this.get(to));
  178. });
  179. }
  180. return false;
  181. },
  182. back: function() {
  183. if(this._current > 0) {
  184. var from = this._current, to = this._current - 1;
  185. this.goTo(to, function(){
  186. this.trigger('back', this.get(from), this.get(to));
  187. });
  188. }
  189. return false;
  190. },
  191. first: function() {
  192. return this.goTo(0);
  193. },
  194. finish: function() {
  195. if(this._current === this.lastIndex()){
  196. var current = this.current();
  197. if(current.validate()){
  198. this.trigger('finish');
  199. current.leave('error');
  200. current.enter('done');
  201. } else {
  202. current.enter('error');
  203. }
  204. }
  205. },
  206. reset: function() {
  207. this._current = 0;
  208. $.each(this.steps, function(i, step){
  209. step.reset();
  210. });
  211. this.trigger('reset');
  212. }
  213. });