precyx
1/3/2020 - 9:44 AM

Form Validation

Basic Validation of fields in React

files

  • form.tsx
  • Validation.tsx
import { isValid, getMessage, Fields } from "../Validation/Validation";


/**
 * Validates all form fields
 */
private validateAllFormFields = () => {
  let _allValid = true;

  for (let key of Object.keys(this.state.formFields)) {
    let _val = this.state.formFields[key];

    if (Fields[key]) {
      if (!this.validateFormField(key, _val)) _allValid = false;
    }
  }

  return _allValid;
}


/**
 * Validates a form field and saves error state
 */
private validateFormField = (field: string, val: any) => {

  let _formErrors = Object["assign"](this.state.formErrors, {});

  let _isValid = isValid(field, val);
  if (_isValid) {
    delete _formErrors[field];
  }
  else {
    _formErrors[field] = getMessage(field, val);
  }

  this.setState({
    formErrors: _formErrors
  });
  return _isValid;
}


/**
 * Handles any form change
 */
private handleChange = (field: string, val: any) => {

  let _formFields = Object["assign"](this.state.formFields, {});
  _formFields[field] = val;

  this.validateFormField(field, val);
  this.setState({
    formFields: _formFields,
  });
}


private handleChangeText = field => evt => {
  this.handleChange(field, evt.target.value);
}

private handleChangeDate = field => date => {
  this.handleChange(field, date);
}

private handleChangeUser = field => user => {
  this.handleChange(field, user.loginName);
}

private handleChangeTaxonomy = field => (terms: IPickerTerms) => {
  this.handleChange(field, terms);
}

private handleChangeCheckbox = field => (e) => {
  this.handleChange(field, e.target.checked);
}

interface IField {
  type: string;
  message: string;
}

/**
 * Fields - with validation type and message
 */
export const Fields: { [key: string]: IField } = {
  "processNumber": {
    type: "required",
    message: "Prozessnummer ist ein Pflichtfeld"
  },
  "releaseBy": {
    type: "requiredArray",
    message: "Freigabe durch ist ein Pflichtfeld"
  },
  "publishOn": {
    type: "required",
    message: "Freigabe am ist ein Pflichtfeld"
  },
  "nextPublishOn": {
    type: "required",
    message: "Nächste Freigabe ist ein Pflichtfeld"
  },
  "taxonomyDokumentArt": {
    type: "requiredArray",
    message: "Dokumentart ist ein Pflichtfeld"
  },
  "taxonomyDatenschutzklasse": {
    type: "requiredArray",
    message: "Datenschutzklasse ist ein Pflichtfeld"
  },
  "taxonomyGeltungsbereich": {
    type: "requiredArray",
    message: "Geltungsbereich ist ein Pflichtfeld"
  }
};

/**
 * Validations
 */
export const Validations: { [key: string]: (val: any) => {} } = {
  "required": (val) => {
    if (val) return true;
    else return false;
  },
  "requiredArray": (val) => {
    if (val && val.length) return true;
    else return false;
  },
};


/**
 * Checks if a specific field is valid
 */
export const isValid = (key: string, value: any) => {

  let _field = Fields[key];
  let _validationtype = _field ? _field.type : "";

  let _validation = Validations[_validationtype];
  return _validation ? _validation(value) : false;
};

/**
 * Gets error message of a field
 */
export const getMessage = (key: string, value: any) => {
  let _field = Fields[key];
  return _field ? _field.message : "";
};