Home > other >  Difficulty prioritizing functions from one class to another
Difficulty prioritizing functions from one class to another

Time:09-17

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(...),
])
  • Related