Create dynamic form in React Js

Add form fields by clicking button in React Js

Posted by Luke Beeno on November 3, 2022

Create dynamic form in React Js

Add form fields by clicking button in React Js

Posted by Luke Beeno on November 3, 2022

In this lesson we will learn how to add form input feilds dynamically in react js. React functional components will be used to illustrate this task. Please install react-boostrap, mdbreact and bootstrap if you want to copy the styling.

Step 1. Create a form with input fields

import "bootstrap/dist/css/bootstrap.min.css";
import {Form} from "react-bootstrap";
import {MDBInput} from "mdbreact";
import {useRef, useState} from 'react';

function App() {
  const [formValues, setFormValues] = useState([{ firstname: "", lastname: "", email: "", phonenumber: ""}])

  return (
      <div className="container">
          <div className="mx-auto col-6 mt-5 mb-4">
              <Form  onSubmit={handleSubmit}>
                {formValues.map((element, index) => (
                    <div className="form-inline" key={index}>
                      <h4>Referral Details {index+1}</h4>
                        <div className="form-group">
                            <label className="form-label">First name</label>
                            <MDBInput type="text" name="firstname" value={element.firstname || ""} onChange={e => handleChange(index, e)} />
                        </div>
                        <div className="form-group">
                            <label className="form-label">Last name</label>
                            <MDBInput type="text" name="lastname" value={element.lastname || ""} onChange={e => handleChange(index, e)} />
                        </div>
                        <div className="form-group">
                            <label className="form-label">Email</label>
                            <MDBInput type="email" name="email" value={element.email || ""} onChange={e => handleChange(index, e)} />
                        </div>
                        <div className="form-group">
                            <label className="form-label">Phone number</label>
                            <MDBInput type="number" name="phonenumber" value={element.phonenumber || ""} onChange={e => handleChange(index, e)} />
                        </div>
                    </div>
                ))}
                <div className="col-6">
                  <button className="btn btn-dark me-3" type="button" onClick={() => addFormFields()}>Add Another referral</button>
                  <button className="btn btn-success" type="submit">Send</button>
                </div>
              </Form>
          </div>
      </div>
  )
}

export default App;

In the above code the React useState that set the input values. The map() method is used to iterate over the input elements.

Step 2. Add function to add form fields

  const handleChange = (i, e) => {
    let newFormValues = [...formValues];
    newFormValues[i][e.target.name] = e.target.value;
    setFormValues(newFormValues);
  }

  const addFormFields = () => {
    setFormValues([...formValues, { firstname: "", lastname: "", email: "", phonenumber: ""}]);
  }

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(JSON.stringify(formValues));
  }

The methods added is:

  • The handleChange method is used to set the input fields values. 
  • The addFormFields is used to add more new input fields
  • The handleSubmit takes all the input values to be stored or transferred

Step 3. Add scroll function 

const myRef = useRef();

setTimeout( () => myRef.current?.scrollIntoView({ behavior: 'smooth'}), 200 );


The scrollIntoView is used to keep the buttons in view. 

Here is the full example:

import "bootstrap/dist/css/bootstrap.min.css";
import {Form} from "react-bootstrap";
import {MDBInput} from "mdbreact";
import {useRef, useState} from 'react';

function App() {
  const [formValues, setFormValues] = useState([{ firstname: "", lastname: "", email: "", phonenumber: ""}])
  const myRef = useRef();

  const handleChange = (i, e) => {
    let newFormValues = [...formValues];
    newFormValues[i][e.target.name] = e.target.value;
    setFormValues(newFormValues);
  }

  const addFormFields = () => {
    setFormValues([...formValues, { firstname: "", lastname: "", email: "", phonenumber: ""}]);
      setTimeout( () => myRef.current?.scrollIntoView({ behavior: 'smooth'}), 200 );
  }

  const handleSubmit = (event) => {
    event.preventDefault();
    alert(JSON.stringify(formValues));
  }

  return (
      <div className="container">
          <div className="mx-auto col-6 mt-5 mb-4">
              <Form  onSubmit={handleSubmit}>
                {formValues.map((element, index) => (
                    <div className="form-inline" key={index}>
                      <h4>Referral Details {index+1}</h4>
                        <div className="form-group">
                            <label className="form-label">First name</label>
                            <MDBInput type="text" name="firstname" value={element.firstname || ""} onChange={e => handleChange(index, e)} />
                        </div>
                        <div className="form-group">
                            <label className="form-label">Last name</label>
                            <MDBInput type="text" name="lastname" value={element.lastname || ""} onChange={e => handleChange(index, e)} />
                        </div>
                        <div className="form-group">
                            <label className="form-label">Email</label>
                            <MDBInput type="email" name="email" value={element.email || ""} onChange={e => handleChange(index, e)} />
                        </div>
                        <div className="form-group">
                            <label className="form-label">Phone number</label>
                            <MDBInput type="number" name="phonenumber" value={element.phonenumber || ""} onChange={e => handleChange(index, e)} />
                        </div>
                    </div>
                ))}
                <div ref={myRef} className="col-6">
                  <button className="btn btn-dark me-3" type="button" onClick={() => addFormFields()}>Add Another referral</button>
                  <button className="btn btn-success" type="submit">Send</button>
                </div>
              </Form>
          </div>
      </div>
  )
}

export default App;