Built files from Bizgaze WebServer
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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. }