Basic Level Dynamic Fields Creation - salimakhtar92/ReactJs GitHub Wiki

Dynamic Fields Creation with Validation rules from a JSON file


import React, { useState } from "react";

const FIELDS = [
  {
    fieldName: "firstName",
    labelName: "First Name",
    inputType: "text",
    isMandatory: true
  },
  {
    fieldName: "lastName",
    labelName: "Last Name",
    inputType: "text",
    isMandatory: true
  },
  {
    fieldName: "age",
    labelName: "Age",
    inputType: "number",
    isMandatory: true
  },
  {
    fieldName: "rollNumber",
    labelName: "Roll No",
    inputType: "number",
    isMandatory: true
  }
];

class Validator {
  constructor(rules) {
    this.validationRules = rules;
    this.sessionValidations = {
      current: "",
      validationRules: []
    };
  }

  validate = (state) => {
    let rulesList = [];
    const keys = Object.keys(state);
    if (keys.length === 1) {
      const key = keys[0];
      rulesList = this.validationRules.filter(
        (field) => field.fieldName === key
      );
    } else {
      rulesList = this.validationRules;
    }
    return this.applyValidationRules(state, rulesList);
  };

  applyValidationRules(state, vRules) {
    let validations = this.valid(vRules);
    vRules.forEach((rule) => {
      const fieldValue = state[rule.fieldName];
      if (!fieldValue) {
        this.inValid(validations, rule);
      }
    });
    return validations;
  }

  valid = (rules) => {
    const validationObject = { isValid: true };
    rules.forEach((rule) => {
      validationObject[rule.fieldName] = { isInvalid: false, message: "" };
    });
    return validationObject;
  };

  inValid = (validations, rule) => {
    validations.isValid = false;
    validations[rule.fieldName] = { isInvalid: true, message: rule.message };
    return validations;
  };
}

const ceateValidationRules = () => {
  return FIELDS.filter((field) => field.isMandatory).map((field) => ({
    fieldName: field.fieldName,
    message: `${field.labelName} is required`
  }));
};

export default function App() {
  const validator = new Validator(ceateValidationRules());
  const [requestObject, setRequestObject] = useState({});
  const [validations, setValidations] = useState({});

  const onChangeHandler = (event) => {
    const { id, value } = event.target;
    requestObject[id] = value;
    setRequestObject(requestObject);
    const newValidations = validator.validate({ [id]: value });
    setValidations({ ...validations, ...newValidations });
  };
  const onSubmitHandler = () => {
    const requestParams = {
      fieldName: "",
      lastName: "",
      age: "",
      ...requestObject
    };
    const validations = validator.validate(requestParams);
    setValidations(validations);
    setRequestObject(requestParams);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {FIELDS.map((field) => (
        <div key={field.fieldName}>
          <label>{field.labelName}</label>
          <input
            type={field.inputType}
            id={field.fieldName}
            name={field.fieldName}
            value={requestObject[field.fieldName]}
            onChange={onChangeHandler}
          />
          {validations &&
            validations[field.fieldName] &&
            validations[field.fieldName].isInvalid && (
              <span>{validations[field.fieldName].message}</span>
            )}
        </div>
      ))}
      <button onClick={onSubmitHandler}>Submit</button>
    </div>
  );
}

⚠️ **GitHub.com Fallback** ⚠️