I want make a form validation. I create a validation methods file:
ValidationMethods.js
export class ValidationMethods {
empty(inputName, errorMessage) {
let validation = false;
if (inputName.value === '') {
validation = true
}
this.result(inputName, errorMessage, validation, 'empty-validation-class')
}
minimum(inputName, min, errorMessage) {
let validation = false;
if (0 < inputName.value.length && inputName.value.length < min) {
validation = true
}
this.result(inputName, errorMessage, validation, 'min-validation-class')
}
maximum(inputName, max, errorMessage) {
let validation = false;
if (inputName.value.length > max) {
validation = true
}
this.result(inputName, errorMessage, validation, 'max-validation-class')
}
result(inputName, errorMessage, validation, classList) {
const className = inputName.name '-validation'
if (validation) {
if (document.getElementsByClassName(className).length <= 0) {
const error = document.createElement('div')
error.classList.add(className, classList)
error.innerHTML = errorMessage
inputName.parentElement.appendChild(error)
inputName.classList.add('validation-error')
inputName.focus()
}
} else {
if (document.getElementsByClassName(classList).length > 0) {
document.querySelector('.' className).remove()
inputName.classList.remove('validation-error')
}
}
}
}
and now I use this class in my new class:
connect(){
let password = document.getElementsByName('password')[0]
const validation = new ValidationMethods()
password.addEventListener('focusout', () => {
validation.minimum(password,3,'Minimum character: 3')
validation.maximum(password,6,'Maximum character: 6')
validation.empty(password,'The field should not be empty')
} )
}
everything all right. But when the empty field should show the error that the field is empty and I add a character, the errors will be cleared and the minimum number of characters error will be displayed when I focuson and focusend the field again. This problem is due to the priority of the field call layout, but can this prioritization be removed in the code?
CodePudding user response:
I guess this is an architectural problem. A validator shouldn't display or clear error messages, only return them. You can try redesigning your code, for example, like this:
Have the basic Validator
class with the following minimal API
class Validator {
// check whether a value is valid
valid(value): boolean;
// return an HTML element with an error message
errorElement(): HTMLDivElement;
}
Make Empty
, Min
, Max
etc extend Validator
and create a central "controller" function which would accept an element and a list of Validators
and perform the actual UI work:
function validate(inputElement, validators) {
// code to clear error messages
//...
// check all validators
let failedValidators = validators.filter(v =>
!v.valid(inputElement.value))
// if any of them failed, display error messages
if (failedValidators.length) {
let errorBox = document.createElement('div')
failedValidators.forEach(v =>
errorBox.appendChild(v.errorElement()))
//etc
}
}
In your event handler, invoke validate
and give it a list of Validator
objects:
password.addEventListener('focusout', event => validate(event.target, [
new EmptyValidator(...),
new MinValidator(...),
new MaxValidator(...),
])