You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
validator/src/formValidator.js

189 lines
4.1 KiB

import validate from 'validate.js'
import serialize from 'form-serialize'
/**
* Form Validator with RiotJS Components
*
*
* @author HerrHase
*
*/
class FormValidator
{
/**
*
* @param {[type]} formSelector [description]
* @param {[type]} constraits [description]
*/
constructor(formElement, constraits, addSubmitEvent = false)
{
// constraits for validate.js
this.constraits = constraits
// get form and elements
this.formElement = formElement
// if form not found
if (!this.formElement) {
console.error('FormValidator: form not found!')
}
this.elements = this.formElement.querySelectorAll('field-error')
// adding event if a element is updated
this.formElement.addEventListener('field-update', (event) => {
this._onFieldUpdate(event)
})
// adding submit event
if (addSubmitEvent) {
this.formElement.addEventListener('submit', (event) => {
this._onSubmit(event)
})
}
}
/**
* trigger submit
*
* @param {object} event
*
*/
submit(event)
{
this._onSubmit(event)
}
/**
*
* @param {function} onError
*
*/
onError(onError)
{
this._onError = onError
}
/**
* settin onSuccess callback and add submit-event on form
*
* @param {function} onSuccess
*
*/
onSuccess(onSuccess)
{
// adding onSuccess
this._onSuccess = onSuccess
}
/**
*
* @param {function} onError
*
*/
onBeforeSubmit(onBeforeSubmit)
{
this._onBeforeSubmit = onBeforeSubmit
}
/**
* handle submit
*
*
* @param {Event} event
*
*/
_onSubmit(event)
{
// getting data from target of submit event
const data = serialize(event.target, {
hash: true
})
// options for validate.js
const options = {
fullMessages: false
}
if (this._onBeforeSubmit) {
this._onBeforeSubmit()
}
// check form and getting errors
validate.async(data, this.constraits, options).then(
() => {
this._onSuccess(event, data)
},
(errors) => {
event.preventDefault()
// if onError is set, tha
if (this._onError) {
this._onError(event, errors, data)
}
// send each element a event
this.elements.forEach((element) => {
let elementErrors = false
// check for errors by name
if (errors[element.attributes.name.nodeValue]) {
elementErrors = errors[element.attributes.name.nodeValue]
}
this._dispatchCustomEvent(elementErrors, element)
})
}
)
}
/**
* send update to fields
*
*
* @param {Event} event
*
*/
_onFieldUpdate(event)
{
// workaround, make sure that value for single is undefined if it is empty
if (event.detail.value == '') {
event.detail.value = undefined
}
let errors = validate.single(event.detail.value, this.constraits[event.detail.name])
// search for element by name and dispatch event
this.elements.forEach((element) => {
if (element.attributes.name.nodeValue == event.detail.name) {
this._dispatchCustomEvent(errors, element)
}
})
}
/**
* dispatch event to single element
*
* @param {Array} errors
* @param {Element} element
*
*/
_dispatchCustomEvent(errors, element)
{
let detail = false
if (errors) {
detail = errors
}
const formValidationEvent = new CustomEvent('form-validation', {
'detail': detail
})
element.dispatchEvent(formValidationEvent)
}
}
export default FormValidator