2
\$\begingroup\$

My intention is to have a component that serves as a textbox wrapper and able to set the error state, error message, and allow the parent to pass a function that sets its local error as I did not see a way to read from the child component's state.

Current known limitations:

  • Can only pass a single value to the validation function which will be the event target value
  • Will only return 1 error at a time, attempting to format helper text with jsx would only show [object]

Component:

import * as React from 'react';
import * as _ from 'lodash'
import { IValidationItem } from '../../../Interfaces/IValidationItem'
import TextField, { TextFieldProps } from "@material-ui/core/TextField";

interface IValidatedTextFieldProps {
    validate?: IValidationItem[],
    validateon?: 'onBlur' | 'onChange',
    validationerror?: (hasError?: boolean) => void
}

interface IValidatedTextFieldState {
    validationErrorMessage: string,
    validationError: boolean
}


type ValidatedTextFieldAllProps = IValidatedTextFieldProps & TextFieldProps

class ValidatedTextField extends React.Component<ValidatedTextFieldAllProps, IValidatedTextFieldState> {

    public constructor(props: ValidatedTextFieldAllProps) {
        super(props);
        this.state = {
            validationErrorMessage: "",
            validationError: false
        }
    }
    public validationWrapper = (event: any) => {

        const { validate, } = this.props;
        return !validate ? "" : _.forEach(validate, (validationItem: IValidationItem) => {
            const result = !validationItem.func(event.target.value)

            if (result) {
                this.setState({ validationErrorMessage: validationItem.validationMessage });
                this.setState({ validationError: result })
                this.callParentValidationErrorMethod(result)
                return false;
            }
            else {
                this.setState({ validationErrorMessage: "" });
                this.setState({ validationError: result })
                this.callParentValidationErrorMethod(result)
                return;
            }
        });
    };

    public onBlurValidation = (event: any) => {
        const { onBlur, validateon, validate } = this.props;
        if (_.isFunction(onBlur)) { onBlur(event); }
        if (validateon === "onBlur" && !!validate) { this.validationWrapper(event); 
    }

    public onChangeValidation = (event: any) => {
        const { onChange, validateon, validate } = this.props;
        if (_.isFunction(onChange)) { onChange(event); }
        if (validateon === "onChange" && !!validate) { this.validationWrapper(event); };
    }
    public callParentValidationErrorMethod = (hasError: boolean) => {
        if(_.isFunction(this.props.validationerror)) {
            this.props.validationerror(hasError);
        }
    }

    public render() {
        const { validationErrorMessage, validationError } = this.state
        const {validationerror,validate,validateon, ...textFieldProps   } = this.props;
   return (<TextField
       {...textFieldProps}
       onBlur={(event: any) => { this.onBlurValidation(event); }}
       onChange={(event: any) => { this.onChangeValidation(event); }
       }
       error={validationError}
       helperText={validationErrorMessage}
   />)
    }
}

export default ValidatedTextField;

ValidationItem Interface

export interface IValidationItem {
    func: (eventValue?: string) => boolean,
    validationMessage: string
}

ValidationItem implementation

import { IValidationItem  } from '../../Interfaces/IValidationItem';
export class ValidationItem implements IValidationItem {
    public func: (eventValue?: string) => boolean
    public validationMessage: string
    constructor(func: (eventValue?: string) => boolean, validationMessage: string) {
        this.func = func;
        this.validationMessage = validationMessage;
    }
}

Validations List Class

import {ValidationItem} from './ValidationItem';
export class Validations {
public static required =  new ValidationItem((eventValue: string) => !!eventValue , "This Field is Required");
public static allowedNameCharacters =  new ValidationItem((eventValue: string) => { 
    const regularExpression = RegExp('^[a-zA-Z0-9\&\-]+$'); return regularExpression.test(eventValue)} , "Input may only contain alphanumeric, &, or - characters");
public static alphanumericCharactersOnly =  new ValidationItem((eventValue: string) => { 
        const regularExpression = RegExp('^[a-zA-Z0-9]+$'); return regularExpression.test(eventValue)} , "Input may only contain alphanumeric characters");
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.