Thursday, 6 January 2022

Dynamic form in Reactjs

I am generating the form based on the data from API.

Form Data: (Api returns array of object but in my example I have converted it to JSON for better understanding but data is array of object like below)

  [
    {
      "id": "formDescription",
      "label": "Form Description",
      "type": { "name": "text" },
      "value": {
        "value": "Use this request for vaccination status",
        "type": {
          "name": "string"
        }
      },
      "properties": { "viewOnly": "true" },
      "typeName": "text"
    },
    {
      "id": "vaccinated",
      "label": "Vaccinated",
      "type": {
        "values": {
          "vaccinated": "Vaccinated",
          "not_vaccinated": "Not Vaccinated"
        },
        "name": "enum"
      },
      "value": {
        "value": null,
        "type": {
          "name": "string"
        }
      },
      "validationConstraints": [],
      "properties": { "groupName": "Letter Details" },
      "typeName": "enum"
    },
    {
      "id": "dose",
      "label": "Dose",
      "type": {
        "values": {
          "dose_one": "Dose One",
          "dose_two": "Dose Two"
        },
        "name": "enum"
      },
      "value": {
        "value": null,
        "type": {
          "name": "string"
        }
      },
      "validationConstraints": [],
      "properties": { "groupName": "Letter Details" },
      "typeName": "enum"
    },
    {
      "id": "reason",
      "label": "Reason",
      "type": { "name": "string" },
      "value": {
        "value": null,
        "type": {
          "name": "string"
        }
      },
      "validationConstraints": [],
      "properties": { "groupName": "Letter Details", "maxlength": "50" },
      "typeName": "string"
    },
    {
      "id": "doseOneDetails",
      "label": "Dose One Details",
      "type": { "name": "textArea" },
      "defaultValue": null,
      "value": {
        "value": null,
        "type": {
          "name": "string"
        }
      },
      "validationConstraints": [
        { "name": "maxlength", "config": "400", "validator": null }
      ],
      "properties": { "groupName": "Letter Details", "maxlength": "400" },
      "typeName": "textArea"
    },
    {
      "id": "doseTwoDetails",
      "label": "Dose Two Details",
      "type": { "name": "textArea" },
      "defaultValue": null,
      "value": {
        "value": null,
        "type": {
          "name": "string"
        }
      },
      "validationConstraints": [
        { "name": "maxlength", "config": "400", "validator": null }
      ],
      "properties": { "groupName": "Letter Details", "maxlength": "400" },
      "typeName": "textArea"
    }
  ]

So based on this data I need to generate a form. And generating of form is already working as per the below provided example.

Requirement:

Scenario 1:

User selects vaccinated as an option from first select box, then the select box with data as Dose One and Dose Two appears. Then if user select any of the dose then he need to add details on that respective dose.

Scenario 2: (Working Now)

User selects Not Vaccinated as an option from first select box, then the reason select box will be displayed.

Scenario 3: (Working Now)

User selects Other as an option from first select box, then the moreDetails text box will be displayed.

Technical Requirement:

To achieve this condition checks, I have included multiple if..else..if conditions like,

  if (Array.isArray(name) && name.length) {
    const [fieldName] = name;
    if (fieldName === "vaccination_status" && value === "vaccinated") {
      setFieldsToHide(["reason", "moreDetails"]);
    } else if (
      fieldName === "vaccination_status" &&
      value === "not_vaccinated"
    ) {
      setFieldsToHide([
        "dose",
        "doseOneDetails",
        "doseTwoDetails",
        "moreDetails"
      ]);
    } else if (fieldName === "vaccination_status" && value === "other") {
      setFieldsToHide([
        "reason",
        "dose",
        "doseOneDetails",
        "doseTwoDetails"
      ]);
    }
  }

So for example if my form grows and in the first select box if more options are added then after selecting an option from first select box, the second select/input box gets displayed. If second one is a select box then again based on that the next select/input box gets displayed and goes on.

In the above given example consider vaccination. Once user selects the vaccination, the dose select box gets displayed then after the dose the respective dose details input box gets displayed. (So one depends on another is the requirement).

Working Example:

Edit antd typescript (forked)

How can we remove this multiple if...else...if condition check with hard coded values and make it configurable may be by modifying the original data structure or some other way?



from Dynamic form in Reactjs

No comments:

Post a Comment