"use strict"; import $ from "jquery"; import Events from "../_events"; import LANG from "../lang/_en"; import FormValidateField from "./_ui.form.validate.field"; import "../../scss/_components/_ui.form.stepped.scss"; const SteppedForm = (($) => { // Constants const NAME = "jsSteppedForm"; const DATA_KEY = NAME; class SteppedForm { constructor(element) { console.log(`${NAME}: init`); const ui = this; const $element = $(element); $element.data(DATA_KEY, this); if (!$element.find(".steps-counter").length) { $element.prepend(LANG["en"][NAME]["STEPCOUNTER"]); } if (!$element.find(".steps-buttons").length) { $element.append(LANG["en"][NAME]["STEPBUTTONS"]); } ui._currentStepCounter = $element.find(".steps-counter .current-step"); ui._totalStepsCounter = $element.find(".steps-counter .total-steps"); ui._steps = $element.find(".step"); ui._steps.each((i, el) => { const $el = $(el); if (!$el.data("step")) { $el.data("step", i + 1); $el.attr("data-step", i + 1); } }); ui._stepNext = $element.find(".step-next"); ui._stepPrev = $element.find(".step-prev"); ui._actions = $element.children(".btn-toolbar,.form-actions"); ui._element = element; ui._currentStep = 1; ui._totalSteps = ui._steps.last().data("step") || ui._steps.length; ui._stepsOrder = []; ui._totalStepsCounter.text(ui._totalSteps); // check if one of the steps already has an error const $hasError = ui._steps .find( ".field.error,.field.holder-error,.field.holder-validation,.field.holder-info,.field.holder-warning,.field.holder-good" ) .first(); if ($hasError.length) { const $modal = $element.parents(".modal"); // show modal if ($modal.length && typeof $modal.modal !== "undefined") { $modal.modal("show"); } ui._currentStep = $hasError.parents(".step").data("step") || ui._currentStep; } // ui.step(`.step[data-step="${ui._currentStep}"]`); ui._stepNext.on("click", (e) => { e.preventDefault(); ui.next(); }); ui._stepPrev.on("click", (e) => { e.preventDefault(); ui.prev(); }); $element.find(".step-toggle").on("click", (e) => { const $el = $(e.currentTarget); e.preventDefault(); ui.step($el.data("target")); }); $element.addClass(`${NAME}-active`); $element.trigger(Events.FORM_INIT_STEPPED); } // Public methods dispose() { console.log(`${NAME}: dispose`); const ui = this; const $element = $(ui._element); $element.removeClass(`${NAME}-active`); $.removeData(ui._element, DATA_KEY); ui._element = null; } next() { const ui = this; if (ui._currentStep >= ui._totalSteps) { return; } ui.step(`.step[data-step="${ui._currentStep + 1}"]`); } prev() { const ui = this; if (ui._currentStep <= 1) { return; } ui.step(ui._stepsOrder[ui._currentStep - 1]); } step(target) { const ui = this; const $element = $(ui._element); const $target = $element.find(target); const targetStep = parseInt($target.data("step")); // validate current step let valid = true; if (targetStep > ui._currentStep) { ui.currentStep() .find("input,textarea,select") .each((i, el) => { const $el = $(el); const fieldUI = $el.data("jsFormValidateField"); if (fieldUI && !fieldUI.validate()) { valid = false; } }); } if (!valid) { return false; } // if (parseInt($target.data("step")) <= "1") { ui._stepPrev.hide(); $element.trigger(Events.FORM_STEPPED_FIRST_STEP); } else { ui._stepPrev.show(); } if (parseInt($target.data("step")) >= ui._totalSteps) { ui._stepNext.hide(); ui._actions.show(); $element.trigger(Events.FORM_STEPPED_LAST_STEP); } else { ui._stepNext.show(); ui._actions.hide(); } ui._currentStep = targetStep; ui._stepsOrder[ui._currentStep] = $target; ui._steps.removeClass("active"); $target.addClass("active"); ui._currentStepCounter.text(ui._currentStep); $target.trigger(Events.FORM_STEPPED_NEW_STEP); $element.trigger(Events.FORM_STEPPED_NEW_STEP); } currentStep() { const ui = this; const $element = $(ui._element); return $element.find(".step.active"); } static _jQueryInterface() { return this.each(function () { // attach functionality to element const $element = $(this); let data = $element.data(DATA_KEY); if (!data) { data = new SteppedForm(this); $element.data(DATA_KEY, data); } }); } } // jQuery interface $.fn[NAME] = SteppedForm._jQueryInterface; $.fn[NAME].Constructor = SteppedForm; $.fn[NAME].noConflict = function () { $.fn[NAME] = JQUERY_NO_CONFLICT; return SteppedForm._jQueryInterface; }; // auto-apply $(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => { $(".form-stepped").jsSteppedForm(); }); return SteppedForm; })($); export default SteppedForm;