Built files from Bizgaze WebServer
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

MultiStep.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. ! function(root, factory) {
  2. 'use strict';
  3. if (typeof define === 'function' && define.amd) {
  4. // AMD
  5. define(['jquery'], function($) {
  6. return factory($, window, document);
  7. });
  8. } else if (typeof exports === 'object') {
  9. // CommonJS
  10. module.exports = function(root, $) {
  11. if (!root) {
  12. root = window;
  13. }
  14. if (!$) {
  15. $ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
  16. require('jquery') :
  17. require('jquery')(root);
  18. }
  19. return factory($, root, root.document);
  20. };
  21. } else {
  22. // Browser
  23. factory(jQuery, window, document);
  24. }
  25. }(this, function($, w, d) {
  26. 'use strict';
  27. var _multiModalClass = 'multi-step';
  28. var _modalHeaderClass = 'modal-header';
  29. var _modalBodyClass = 'modal-body';
  30. var _modalFooterClass = 'modal-footer';
  31. var _modalStepsClass = 'modal-steps';
  32. var _stepDotClass = 'dot';
  33. var _stepLabelClass = 'label';
  34. var _stepClass = 'step';
  35. var _stepContentContainerClass = 'step-content-container';
  36. var _stepContentClass = 'step-content';
  37. var _contentInnerClass = 'content-inner';
  38. var _prevClass = 'btn-prev';
  39. var _skipClass = 'btn-skip';
  40. var _nextClass = 'btn-next';
  41. var _currentClass = 'current';
  42. var _completedClass = 'completed';
  43. var _skippedClass = 'skipped';
  44. var _disabledClass = 'disabled';
  45. var _skippableClass = 'skippable';
  46. var defaults = {
  47. data: [],
  48. final: 'Are you sure you want to confirm?',
  49. finalLabel: 'Complete',
  50. title: '',
  51. prevText: 'Previous',
  52. skipText: 'Skip',
  53. nextText: 'Next',
  54. finishText: 'Finish',
  55. modalSize: 'md',
  56. onClose: function() {
  57. },
  58. onDestroy: function($elem) {
  59. }
  60. };
  61. var multiStep = function($element, options) {
  62. var $this = this;
  63. this.element = $element;
  64. this.options = $.extend({}, defaults, options);
  65. this.destroy = function() {
  66. this.element.html('');
  67. var id = this.element.attr('data-id')
  68. this.element.attr('id', id);
  69. this.element.removeAttr('data-id')
  70. .removeAttr('class')
  71. .removeAttr('tabindex')
  72. .removeAttr('role')
  73. .removeAttr('aria-labelledby')
  74. .removeAttr('aria-hidden');
  75. this._onDestroy();
  76. }
  77. this.init();
  78. };
  79. function uuidv4() {
  80. return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
  81. (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  82. )
  83. }
  84. multiStep.prototype = {
  85. constructor: multiStep,
  86. init: function() {
  87. this._buildModal();
  88. this._buildMultiStep();
  89. },
  90. update: function(options) {
  91. this.options = $.extend({}, this.options, options);
  92. this.init();
  93. },
  94. _buildMultiStep: function() {
  95. var $element = this.element;
  96. var id = $element.attr('id')
  97. if (!id || id.trim() == '') {
  98. id = uuidv4();
  99. $element.attr('id', id);
  100. }
  101. this.id = id;
  102. $element.addClass(_multiModalClass);
  103. var $header = $element.find(`.${_modalHeaderClass}`);
  104. this.header = $header;
  105. $header.append(`<div class="${_modalStepsClass}"></div>`);
  106. var $modalSteps = $header.find(`.${_modalStepsClass}`);
  107. this.modalSteps = $modalSteps;
  108. var $body = $element.find(`.${_modalBodyClass}`);
  109. this.body = $body;
  110. var $footer = $element.find(`.${_modalFooterClass}`);
  111. this.footer = $footer;
  112. this._buildDataContent();
  113. this._buildFooterContent();
  114. this._attachEvents();
  115. this._initialModal();
  116. },
  117. _buildModal: function() {
  118. var id = this.element.attr('id');
  119. var dataId = id;
  120. if (this.options.id) {
  121. id = this.options.id;
  122. }
  123. if (!id) {
  124. id = uuidv4();
  125. }
  126. this.element.attr('id', id)
  127. .attr('data-id', dataId)
  128. .attr('class', 'modal fade')
  129. .attr('tabindex', '-1')
  130. .attr('role', 'dialog')
  131. .attr('aria-labelledby', `${id}Title`)
  132. .attr('aria-hidden', 'true');
  133. this.element.html(`<div class="modal-dialog modal-dialog-centered modal-${this.options.modalSize} multi-step" role="document"><div class="modal-content"><div class="modal-header py-2"><div id="div_errroMessage" class="w-80 font-weight-400" style="margin:auto"></div><a href="javascript:;" class="close-btn" data-dismiss="modal"><i class="text-dark la la-times"></i></a></div><div class="modal-body h-430p py-2"></div><div class="modal-footer py-2"></div></div></div>`);
  134. var $this = this;
  135. this.element.on('hide.bs.modal', function() {
  136. $this._initialModal();
  137. $this._onClose();
  138. }).on('hidden.bs.modal', function() {
  139. $this._initialModal();
  140. $this._onClose();
  141. })
  142. },
  143. _onClose: function() {
  144. if (typeof this.options.onClose == 'function') {
  145. this.options.onClose(this.element);
  146. }
  147. },
  148. _onDestroy: function() {
  149. if (typeof this.options.onDestroy == 'function') {
  150. this.options.onDestroy();
  151. }
  152. },
  153. _buildDataContent: function() {
  154. var data = this.options.data;
  155. if (data && data.length > 0) {
  156. var steps = '';
  157. var stepContent = '';
  158. this.data = data;
  159. this.stepsCount = data.length;
  160. for (var i in data) {
  161. var currentStep = Number(i) + 1;
  162. var stepLabel = data[i].label ? data[i].label : `Step ${currentStep}`;
  163. steps += `<div class="${_stepClass}" data-step="${currentStep}" data-step-skip=${data[i].skip==true}>
  164. <div class="${_stepDotClass}"></div>
  165. <label class="${_stepLabelClass}">${stepLabel}</label>
  166. </div>`;
  167. stepContent += `<div class="${_stepContentClass}" data-step="${currentStep}" data-step-skip=${data[i].skip==true}>
  168. <div class="${_contentInnerClass}">${data[i].content}</div>
  169. </div>`
  170. }
  171. steps += `<div class="${_stepClass}" data-step="${data.length+1}" data-step-skip=false>
  172. <div class="${_stepDotClass}"></div>
  173. <label class="${_stepLabelClass}">${this.options.finalLabel}</label>
  174. </div>`;
  175. stepContent += `<div class="${_stepContentClass}" data-step="${data.length+1}" data-step-skip=false>
  176. <div class="${_contentInnerClass}">${this.options.final}</div>
  177. </div>`
  178. this.modalSteps.html(steps);
  179. stepContent = `<div class="${_stepContentContainerClass}">${stepContent}</div>`;
  180. this.body.html(stepContent);
  181. this.stepContentContainer = this.body.find(`.${_stepContentContainerClass}`);
  182. }
  183. },
  184. _buildFooterContent: function() {
  185. var footer = `<a href="javascript:;" id="multi_Step-prev" class="btn btn-sm btn-primary multi_Step-prev ${_prevClass}">${this.options.prevText}</a>
  186. <a href="javascript:;" class="btn btn-sm ${_skipClass} btn-primary">${this.options.skipText}</a>
  187. <a href="javascript:;" class="btn btn-sm btn-primary" data-isNext="true">NEXT</a>
  188. <a href="javascript:;" id="multi_Step-next" class="d-none btn btn-sm btn-primary multi_Step-next ${_nextClass}">${this.options.nextText}</a>`;
  189. this.footer.html(footer);
  190. this.prev = this.footer.find(`.${_prevClass}`);
  191. this.skip = this.footer.find(`.${_skipClass}`);
  192. this.next = this.footer.find(`.${_nextClass}`);
  193. },
  194. _attachEvents: function() {
  195. this._attachPrevEvent();
  196. this._attachSkipEvent();
  197. this._attachNextEvent();
  198. },
  199. _attachPrevEvent: function() {
  200. var $this = this;
  201. $this.prev.click(function() {
  202. $this.next.text($this.options.nextText);
  203. var prevIdx = $this.currentStepIdx - 1;
  204. if (prevIdx <= 1) {
  205. prevIdx = 1;
  206. $this.prev.addClass(_disabledClass).attr(_disabledClass, _disabledClass);
  207. } else {
  208. $this.prev.removeClass(_disabledClass).removeAttr(_disabledClass);
  209. }
  210. $this._currentStep(prevIdx);
  211. $this._checkSkip();
  212. $this._showContent(prevIdx);
  213. });
  214. },
  215. _checkSkip: function() {
  216. var skipStep = this.modalSteps.find(`.${_currentClass}`).attr('data-step-skip') == 'true';
  217. if (skipStep) {
  218. this.skip.addClass(_skippableClass);
  219. } else {
  220. this.skip.removeClass(_skippableClass);
  221. }
  222. },
  223. _attachSkipEvent: function() {
  224. var $this = this;
  225. $this.skip.click(function() {
  226. var nextIdx = $this.currentStepIdx;
  227. if (nextIdx + 1 <= 1) {
  228. $this.prev.addClass(_disabledClass).attr(_disabledClass, _disabledClass);
  229. } else {
  230. $this.prev.removeClass(_disabledClass).removeAttr(_disabledClass);
  231. }
  232. $this._skipStep(nextIdx);
  233. $this._showContent(nextIdx + 1);
  234. });
  235. },
  236. _attachNextEvent: function() {
  237. var $this = this;
  238. $this.next.click(function() {
  239. var nextIdx = $this.currentStepIdx;
  240. if (nextIdx >= $this.stepsCount + 1) {
  241. $this.element.modal('hide');
  242. return;
  243. }
  244. if (nextIdx >= $this.stepsCount) {
  245. $this.next.text($this.options.finishText);
  246. } else {
  247. $this.next.text($this.options.nextText);
  248. }
  249. if (nextIdx + 1 <= 1) {
  250. $this.prev.addClass(_disabledClass).attr(_disabledClass, _disabledClass);
  251. } else {
  252. $this.prev.removeClass(_disabledClass).removeAttr(_disabledClass);
  253. }
  254. $this._completeStep(nextIdx);
  255. $this._showContent(nextIdx + 1);
  256. });
  257. },
  258. _currentStep: function(i) {
  259. var idx = this.modalSteps.find(`[data-step]`).length;
  260. this._recursiveCurrentStep(i, idx);
  261. this.currentStepIdx = i;
  262. },
  263. _showContent: function(i) {
  264. var $this = this;
  265. if (this.stepContentContainer) {
  266. this.stepContentContainer.find(`.${_stepContentClass}`).removeClass('active');
  267. this.stepContentContainer.find(`[data-step="${i}"]`).addClass('active');
  268. }
  269. },
  270. _recursiveCurrentStep: function(target, i) {
  271. if (i < 1) {
  272. return;
  273. }
  274. var currentStep = this.modalSteps.find(`[data-step="${i}"]`);
  275. var $this = this;
  276. if (target == i) {
  277. currentStep.removeClasses([_completedClass, _skippedClass]).addClass(_currentClass);
  278. $this._checkSkip();
  279. } else {
  280. if (currentStep.hasAnyClass([_completedClass, _currentClass, _skippedClass])) {
  281. currentStep.removeClasses([_completedClass, _currentClass, _skippedClass]);
  282. setTimeout(function() {
  283. $this._recursiveCurrentStep(target, --i);
  284. }, 200);
  285. } else {
  286. $this._recursiveCurrentStep(target, --i);
  287. }
  288. }
  289. },
  290. _completeStep: function(i) {
  291. var $this = this;
  292. this.modalSteps.find(`[data-step="${i}"]`).addClass(_completedClass).removeClasses([_currentClass, _skippedClass]);
  293. setTimeout(function() {
  294. $this.modalSteps.find(`[data-step="${Number(i)+1}"]`).addClass(_currentClass);
  295. $this.currentStepIdx = Number(i) + 1;
  296. $this._checkSkip();
  297. }, 200);
  298. },
  299. _skipStep: function(i) {
  300. var $this = this;
  301. this.modalSteps.find(`[data-step="${i}"]`).addClass(_skippedClass).removeClasses([_currentClass, _completedClass]);
  302. setTimeout(function() {
  303. $this.modalSteps.find(`[data-step="${Number(i)+1}"]`).addClass(_currentClass);
  304. $this.currentStepIdx = Number(i) + 1;
  305. $this._checkSkip();
  306. }, 200);
  307. },
  308. _initialModal: function() {
  309. this._currentStep(1);
  310. this.prev.addClass(_disabledClass).attr(_disabledClass, _disabledClass);
  311. this._checkSkip();
  312. this._showContent(1);
  313. this.next.text(this.options.nextText);
  314. }
  315. }
  316. $.fn.MultiStep = function(options, callback) {
  317. if (typeof options == 'object') {
  318. options = $.extend(true, {}, defaults, options);
  319. }
  320. this.each(function() {
  321. var $this = $(this);
  322. if (!$this.data('multiStep') && (options ? typeof options == 'object' : true)) {
  323. $this.data('multiStep', new multiStep($this, options));
  324. } else if ($this.data('multiStep')) {
  325. if (typeof options == 'string') {
  326. var func = options;
  327. var params = callback;
  328. $this.data('multiStep')[func].call(params);
  329. } else {
  330. $this.data('multiStep').update(options);
  331. }
  332. }
  333. });
  334. if (typeof callback == 'function') {
  335. callback.call(this.element);
  336. };
  337. return this;
  338. };
  339. $.fn.MultiStep.defaults = defaults;
  340. $.fn.MultiStep.multiStep = multiStep;
  341. $(document).ready(function() {
  342. $('.multi-step').MultiStep();
  343. });
  344. });
  345. $.fn.removeClasses = function(arr) {
  346. if (typeof arr == 'string') {
  347. arr = [arr];
  348. }
  349. for (var i = arr.length - 1; i >= 0; i--) {
  350. var x = arr[i];
  351. this.removeClass(x);
  352. }
  353. return this;
  354. }
  355. $.fn.addClasses = function(arr) {
  356. if (typeof arr == 'string') {
  357. arr = [arr];
  358. }
  359. for (var i = arr.length - 1; i >= 0; i--) {
  360. var x = arr[i];
  361. this.addClass(x);
  362. }
  363. return this;
  364. }
  365. $.fn.hasAnyClass = function(arr) {
  366. if (typeof arr == 'string') {
  367. arr = [arr];
  368. }
  369. for (var i = arr.length - 1; i >= 0; i--) {
  370. var x = arr[i];
  371. if (this.hasClass(x)) {
  372. return true;
  373. }
  374. }
  375. return false;
  376. }