224 lines
5.3 KiB
JavaScript
224 lines
5.3 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
|