224 lines
5.4 KiB
JavaScript
224 lines
5.4 KiB
JavaScript
"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;
|