feature/field-error
Björn 3 years ago
parent d3103d2616
commit 34898a8bd1

File diff suppressed because one or more lines are too long

@ -1,4 +0,0 @@
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ })()
;

@ -2,6 +2,8 @@ import validate from 'validate.js'
import serialize from 'form-serialize' import serialize from 'form-serialize'
/** /**
* Form Validator with RiotJS Components
*
* *
* *
* *
@ -15,8 +17,6 @@ class FormValidator
*/ */
constructor(formSelector, constraits) constructor(formSelector, constraits)
{ {
this.errors = []
// getting selector to find form-element // getting selector to find form-element
this.formSelector = formSelector this.formSelector = formSelector
@ -38,31 +38,13 @@ class FormValidator
}) })
} }
/**
*
* @param {[type]} name [description]
* @return {[type]} [description]
*/
findElementByName(name) {
let result
this.elements.forEach((element) => {
if (element.attributes.name.nodeValue == name) {
result = element
return false
}
})
return result
}
/** /**
* *
* @param {[type]} event [description] * @param {[type]} event [description]
* @return {[type]} [description] * @return {[type]} [description]
*/ */
onSubmit(event) { onSubmit(event)
{
let errors = validate(serialize(event.target, { let errors = validate(serialize(event.target, {
hash: true hash: true
}), this.constraits) }), this.constraits)
@ -70,9 +52,11 @@ class FormValidator
if (errors) { if (errors) {
event.preventDefault() event.preventDefault()
// send each element a event
this.elements.forEach((element) => { this.elements.forEach((element) => {
let elementErrors = false let elementErrors = false
// check for errors by name
if (errors[element.attributes.name.nodeValue]) { if (errors[element.attributes.name.nodeValue]) {
elementErrors = errors[element.attributes.name.nodeValue] elementErrors = errors[element.attributes.name.nodeValue]
} }
@ -84,27 +68,35 @@ class FormValidator
/** /**
* *
* @param {[type]} event [description] *
* @return {[type]} [description] * @param {Event} event
*
*/ */
onFieldUpdate(event) { onFieldUpdate(event)
{
// if value is a empty string make him undefined // if value is a empty string make him undefined
if (!event.detail.value) { if (event.detail.value == '') {
event.detail.value = undefined event.detail.value = undefined
} }
let errors = validate.single(event.detail.value, this.constraits[event.detail.name]) let errors = validate.single(event.detail.value, this.constraits[event.detail.name]),
let element = this.findElementByName(event.detail.name) element
this.dispatchCustomEvent(errors, element) // search for element by name and dispatch event
Array.from(this.elements).every((e) => {
if (e.attributes.name.nodeValue == event.detail.name) {
this.dispatchCustomEvent(errors, e)
return false
}
})
} }
/** /**
* dispatch event to single element
*
* @param {Array} errors
* @param {Element} element
* *
* @param {[type]} errors [description]
* @param {[type]} element [description]
* @return {[type]} [description]
*/ */
dispatchCustomEvent(errors, element) dispatchCustomEvent(errors, element)
{ {

@ -9,9 +9,12 @@
<script> <script>
/** /**
* Shows errors of Validation * Shows errors of Validation and raise a element to
* trigger single validation of field
* *
* <field-error name="name" errors={ errors }></field-error> * <field-error name="name" nofieldupdate></field-error>
*
* @author Björn Hase, Tentakelfabrik, me@tentakelfabrik.de
* *
*/ */
@ -23,44 +26,82 @@
], ],
}, },
onMounted(props, state) { /**
*
*
* @param {Object} props [description]
* @param {Object} state [description]
*
*/
onMounted(props, state)
{
// getting parent element for entire field
const parent = this.root.closest('.field') const parent = this.root.closest('.field')
const element = document.querySelector('[name="' + props.name + '"]')
const form = element.closest('form')
// element and form set // getting current element by name
if (element && form) { const element = document.querySelector('[name="' + props.name + '"]')
element.addEventListener('keyup', function(event) {
const fieldUpdateEvent = new CustomEvent('field-update', { // getting form
'detail': { const form = element.closest('form')
'name': props.name,
'value': this.value
}
})
form.dispatchEvent(fieldUpdateEvent) // element, form are exists and nofieldupdate is not set
// each change of the element dispatch a event to form validation
if (element && form && !props.nofieldupdate) {
element.addEventListener('input', (event) => {
this.dispatchCustomEvent(event, form, props.name)
}) })
} }
// add custom event to listen to form-validation // add custom event to listen to form-validation
this.root.addEventListener('form-validation', (event) => { this.root.addEventListener('form-validation', (event) => {
this.onFormValidation(event, parent)
})
},
// if detail is set with element name, get errors /**
if (event.detail) { * process form validation triggered by form
this.state.errors = event.detail *
parent.classList.add('field--error') * @param {Event} event
parent.classList.remove('field--valid') * @param {Element} parent
} else { *
this.state.errors = [] */
parent.classList.remove('field--error') onFormValidation(event, parent)
parent.classList.add('field--valid') {
} // if detail is a value, set to errors
if (event.detail) {
this.state.errors = event.detail
this.update() parent.classList.add('field--error')
parent.classList.remove('field--valid')
} else {
this.state.errors = []
parent.classList.remove('field--error')
parent.classList.add('field--valid')
}
this.update()
},
/**
* create event to send to form validation
*
* @param {Event} event
* @param {Element} form
* @param {string} name
*
*/
dispatchCustomEvent(event, form, name)
{
const fieldUpdateEvent = new CustomEvent('field-update', {
'detail': {
'name': name,
'value': event.target.value
}
}) })
}
form.dispatchEvent(fieldUpdateEvent)
},
} }
</script> </script>

@ -1,92 +0,0 @@
import validate from 'validate.js'
import serialize from 'form-serialize'
/**
* Validate entire Form or a single Element
*
* Using validator.js
*
* @author Björn Hase, Tentakelfabrik, me@tentakelfabrik.de
*
*/
class Validator {
/**
*
* @param {array} rules
*/
constructor(rules, component) {
this._rules = rules
this._component = component
this._errors = {
}
}
/**
* handle validation
*
* if key not set,
*
* @param {object} event
* @param {object} key
*
*/
handle(event, key) {
event.preventDefault()
let data = null, rules, errors
if (key) {
if (event.target.value) {
data = event.target.value
}
} else {
data = serialize(event.target, {
hash: true
})
}
// validate single
if (key) {
rules = this._rules[key]
errors = validate.single(data, rules, {
flat: true
})
if (errors) {
this._errors[key] = errors
} else {
delete this._errors[key]
}
// validate entire form
} else {
this._errors = validate(data, this._rules)
}
// update component
this._component.update()
}
/**
*
*
* @param {[type]} key
* @return {[type]}
*/
errors(key) {
if (key) {
return this._errors[key]
}
return this._errors
}
}
export default Validator
Loading…
Cancel
Save