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;