0

So i am trying to create a dynamic form with a couple of HTML inputs. i have an array of object Forms which contain the type of input that should be rendered. Currently i am able to render a couple of inputs like text area but how do i deal with radios, check boxes, selects along with their options? Any help will be appreciated.

See this CodeSandbox.

Check this Sample Code:-

class App extends React.Component {
  state = {
    Forms: [{
        name: "select",
        type: "select",
        options: ["a", "b", "c"]
      },
      {
        name: "Radio",
        type: "radio",
        options: ["a", "b", "c"]
      },
      {
        name: "Date",
        type: "date",
        value: "2018-07-22"
      },
      {
        name: "Text Input",
        type: "text",
        value: "text input"
      },
      {
        name: "Checkbox",
        type: "checkbox",
        options: ["a", "b", "c"]
      },
      {
        name: "Textarea",
        type: "textarea",
        value: "text area"
      }
    ]
  };

  renderForm = () => {
    return this.state.Forms.map((form, index) => ( <
      label key = {index} > { form.name} 
      <input type = { form.type }
      value = { form.value } /> 
      <select/ >
      </label>
    ));
  };

  render() {
    return <div > {
      this.renderForm()
    } < /div>;
  }
}

export default App;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Thank you for all the help. :)

1
  • You can simply add a switch(form.type) inside your map and return the appropriate component for each case :) Commented Jun 19, 2020 at 0:05

2 Answers 2

2

Something like:

import React from "react";
import "./styles.css";

class App extends React.Component {
  state = {
    Forms: [
      { name: "select", type: "select", options: ["a", "b", "c"] },
      { name: "Radio", type: "radio", options: ["a", "b", "c"] },
      { name: "Date", type: "date", value: "2018-07-22" },
      { name: "Text Input", type: "text", value: "text input" },
      { name: "Checkbox", type: "checkbox", options: ["a", "b", "c"] },
      { name: "Textarea", type: "textarea", value: "text area" }
    ]
  };

  getField = (field) => {
    switch(field.type) {
      case 'date':
      case 'text':
      case 'textarea':
        return <input type={field.type} value={field.value} />;
      case 'select':
          return <select name={field}>
            {field.options.map(option =>
              <option key={option} value={option}>{option}</option>
            )};
          </select>;
      case 'radio':
      case 'checkbox':
          return <div>{field.options.map((option) =>
            <label>
              {option}: 
              <input key={option} type={field.type} name={option} value={option}/>
            </label>
          )}</div>;
      default:
        return <div>Unknown form field</div>;
    }
  }

  renderForm = () => {
    return this.state.Forms.map((field, index) => (
      <label key={index}>
        {field.name}
        {this.getField(field)}
      </label>
    ));
  };

  render() {
    return <div>{this.renderForm()}</div>;
  }
}

export default App;
Sign up to request clarification or add additional context in comments.

Comments

2

You need to handle the different form types differently. See update example:

class App extends React.Component {
  state = {
    Forms: [{
        name: "select",
        type: "select",
        options: ["a", "b", "c"]
      },
      {
        name: "Radio",
        type: "radio",
        options: ["a", "b", "c"]
      },
      {
        name: "Date",
        type: "date",
        value: "2018-07-22"
      },
      {
        name: "Text Input",
        type: "text",
        value: "text input"
      },
      {
        name: "Checkbox",
        type: "checkbox",
        options: ["a", "b", "c"]
      },
      {
        name: "Textarea",
        type: "textarea",
        value: "text area"
      }
    ]
  };

  renderForm = () => {
    return this.state.Forms.map((form, index) => {
      if (form.type === 'checkbox' || form.type === 'radio') {
        return (
          <span>
            {form.name}
            {form.options.map(opt => (
              <label key={opt}>
                <input type={form.type} group={form.name} value={opt} />
                {opt}
              </label>
            ))}
          </span>
        );
      }
      
      if (form.type === 'select') {
        return (
          <label key={index}>{form.name} 
            <select>
              {form.options.map(opt => (
                <option key={opt}>
                  {opt}
                </option>
              ))}
            </select>
          </label>
        );
      }
      
      return (
        <label key={index}>{form.name} 
          <input type={form.type} value={form.value} /> 
        </label>
      );
    });
  };

  render() {
    return <div > {
      this.renderForm()
    } < /div>;
  }
}

ReactDOM.render(<App />, document.querySelector("#app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.