Blog-dynamic-fields

How to create dynamic fields in React Component

Hey Friends,
In this tutorial we’ll know that how we can create dynamic fields in react js. I hope you are aware with the Installation and setup the React application using CRA utility provided by react.
I am assuming that you have already setup a react project. So lets get start it.

create a file named DynamicForm.jsx and add following basic class syntax in it.

import React, { Component } from "react";

class DynamicForm extends Component {
  
  constructor(props) {
    super(props);
  }

  render() {
      return(
          <h1>My Dynamic Form</h1>
       )
  }
}

Now add some initial state in constructor.

 this.state = {
      form: [
        { fullName: "Manvik Singh", age: 3 },
        { fullName: "Manu Singh", age: 5 }
      ]
    };

Loop through the initial data in render method


        {this.state.form &&
          this.state.form.map((item, index) => (
            <div key={index} className="row mt-5 mb-5">
              <div className="col col-md-5">
                <input
                  placeholder="Full Name"
                  className="form-control"
                  type="text"
                  name="fullName"
                  value={item.fullName}
                  onChange={(e) => this.handleChange(e, index)}
                />
              </div>
              <div className="col col-md-5">
                <input
                  placeholder="Age"
                  className="form-control"
                  type="number"
                  name="age"
                  value={item.age}
                  onChange={(e) => this.handleChange(e, index)}
                />
              </div>
              <div className="col col-md-1">
                <button
                  onClick={() => this.handleDelete(index)}
                  className="btn btn-danger"
                >
                  X
                </button>
              </div>
            </div>
          ))}

Noticed we have used handleChange & handleDelete method in above jsx, so lets create those methods as well


handleChange = (e, index) => {
    const items = this.state.form;
    items[index][e.target.name] = e.target.value;
    this.setState({
      form: items
    });
  };
  handleDelete = (index) => {
    const items = this.state.form;
    if (items.length > 1) {
      items.splice(index, 1);
      this.setState({
        form: items
      });
    } else {
      window.alert("Last row cant be delete!");
    }
  };

Now will need Add new row button and save form button, so let them create before the dynamic form fields are rendering

 <div className="row">
          <div className="col col-md-10 text-right">
            <button onClick={this.addNewRow} className="btn btn-secondary">
              +Add New
            </button>
            <button onClick={this.saveAll} className="ml-2 btn btn-primary">
              Save Form
            </button>
          </div>
        </div>

Now above buttons handlers to handle new row and save the updated/filled form data to api/server.


addNewRow = () => {
    const items = this.state.form;
    const blankRow = { fullName: "", age: "" };
    this.setState({
      form: [...items, blankRow]
    });
  };
  saveAll = () => {
    const { form } = this.state;
    //lets check whats in the form now
    console.log("Form data :", form);
    //Now here you may want to call your service or xhr call to send data over the apis
    //like this
    fetch("https://www.w3school.info/apis/bla-bla-api", form)
      .then((res) => res.json())
      .then((response) => console.log("my response is ", response))
      .catch((err) => console.log("error occured", err));
  };

Now All code at one shot


import React, { Component } from "react";

class DynamicForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      form: [
        { fullName: "Manvik Singh", age: 3 },
        { fullName: "Manu Singh", age: 5 }
      ]
    };
  }

  handleChange = (e, index) => {
    const items = this.state.form;
    items[index][e.target.name] = e.target.value;
    this.setState({
      form: items
    });
  };
  handleDelete = (index) => {
    const items = this.state.form;
    if (items.length > 1) {
      items.splice(index, 1);
      this.setState({
        form: items
      });
    } else {
      window.alert("Last row cant be delete!");
    }
  };
  addNewRow = () => {
    const items = this.state.form;
    const blankRow = { fullName: "", age: "" };
    this.setState({
      form: [...items, blankRow]
    });
  };
  saveAll = () => {
    const { form } = this.state;
    //lets check whats in the form now
    console.log("Form data :", form);
    //Now here you may want to call your service or xhr call to send data over the apis
    //like this
    fetch("https://www.w3school.info/apis/bla-bla-api", form)
      .then((res) => res.json())
      .then((response) => console.log("my response is ", response))
      .catch((err) => console.log("error occured", err));
  };

  render() {
    return (
      <>
        <h1>My Dynamic Form</h1>
        <div className="row">
          <div className="col col-md-10 text-right">
            <button onClick={this.addNewRow} className="btn btn-secondary">
              +Add New
            </button>
            <button onClick={this.saveAll} className="ml-2 btn btn-primary">
              Save Form
            </button>
          </div>
        </div>
        {this.state.form &&
          this.state.form.map((item, index) => (
            <div key={index} className="row mt-5 mb-5">
              <div className="col col-md-5">
                <input
                  placeholder="Full Name"
                  className="form-control"
                  type="text"
                  name="fullName"
                  value={item.fullName}
                  onChange={(e) => this.handleChange(e, index)}
                />
              </div>
              <div className="col col-md-5">
                <input
                  placeholder="Age"
                  className="form-control"
                  type="number"
                  name="age"
                  value={item.age}
                  onChange={(e) => this.handleChange(e, index)}
                />
              </div>
              <div className="col col-md-1">
                <button
                  onClick={() => this.handleDelete(index)}
                  className="btn btn-danger"
                >
                  X
                </button>
              </div>
            </div>
          ))}
      </>
    );
  }
}
export default DynamicForm;

Now just Import and Add this component where you want we have called it in App Component like this, putting my App.js code


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

export default function App() {
  return (
    <div className="App">
      <DynamicForm />
    </div>
  );
}

Note : I have used classes from bootstrap css framework, if you haven’t implemented the bootstrap in your project then you may edit
index.html from public folder and add following bootstrap css cdn link to look this demo fine.

put this in head section

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />

This is all I have for this blog, if you have any queries then let me know me via contact us form or do comments below. Also the live
demo for this code is available at https://codesandbox.io/s/dynamic-form-fields-in-react-y6p3e?file=/src/DynamicForm.jsx

Published by

Jeetendra Singh

Jeetendra Singh is a Full Stack Architect who has 12+ Years of Experience into Software Development. He is a Microsoft certified technology Specialist and AWS Certified Associate Architect. His Major Interests are in Mongo Db, Express Js, React Js, Node Js (MERN STACK), Python, DJango, Redis, Mysql, Dynamo DB , Devops, Jenkins, Cloud/Lamda , Fast Api. He build variety of applications using Python, Mern, Mean, Node, JavaScript, jQuery & PHP