Create an Editable Text Field in a Table Using ReactJS [Learn the Trick]

7 min readReactJS
#react-table#components
Create an Editable Text Field in a Table Using ReactJS [Learn the Trick]

Today, we will explore how to build an editable table in React.js; a crucial topic for React developers.

In the ReactJS section of Codevertiser, we have already covered some essential React topics, such as handling forms, creating a quiz app, and many others.

Demo App

This is a Demo App of what we are about to learn and build in this article, you can play with it.

Table with Editable Text Field
NameEmailPosition


Editable text fields in a table enhance the user experience of a React App. It might seem difficult to build, but it becomes easy with the right tricks. There are many ways to create them, but I’ll share the easiest one, so you can do it without getting exhausted. Let's get started.

Codepen Demo | Editable Table

If you are only interested in code, you can find it below on the Codepen widget. However, if you want to learn how to build it step by step, follow the article.

Creating the Editable Text field in Table

Step 01: Create Table

In the first step, create a simple table like we do with plain HTML5. A simple table is created to make the base for the editable text fields. After building the table, we will turn the Table Data: td into an editable text.

jsx
1function EditableTable() { 2 return ( 3 <div> 4 <table> 5 <thead> 6 <tr> 7 <th>Name</th> 8 <th>Email</th> 9 <th>Position</th> 10 </tr> 11 </thead> 12 <tbody> 13 <tr> 14 <td>John Doe</td> 15 <td>johndoe@email.com</td> 16 <td>Frontend Developer</td> 17 </tr> 18 <tr> 19 <td>Sara</td> 20 <td>sara@email.com</td> 21 <td>HR Executive</td> 22 </tr> 23 <tr> 24 <td>Mike</td> 25 <td>mike@email.com</td> 26 <td>Backend Developer Developer</td> 27 </tr> 28 </tbody> 29 </table> 30 </div> 31 ) 32} 33 34export default EditableTable

Now we have to figure out how to turn this td: table data into editable field.

The first thing that came into mind is to wrap input inside td.

Let’s make the code clean

Before moving to Editable Text Field let’s make this component a bit cleaner.

In real-world apps, we get data via APIs. So to mock it, we will build an array of objects.

jsx
1import { useState } from 'react' 2 3const data = [ 4 { 5 id: '01', 6 name: 'John Doe', 7 email: 'johndoe@email.com', 8 position: 'Frontend Developer', 9 }, 10 { 11 id: '02', 12 name: 'Sara', 13 email: 'sara@email.com', 14 position: 'HR Executive', 15 }, 16 { 17 id: '03', 18 name: 'Mike', 19 email: 'mike@email.com', 20 position: 'Backend Developer', 21 }, 22] 23 24const EditableTable = () => { 25 const [employeeData, setEmployeeData] = useState(data) 26 27 return ( 28 <div> 29 <table> 30 <thead> 31 <tr> 32 <th>Name</th> 33 <th>Email</th> 34 <th>Position</th> 35 </tr> 36 </thead> 37 <tbody> 38 {employeeData.map(({ id, name, email, position }) => ( 39 <tr key={id}> 40 <td>{name}</td> 41 <td>{email}</td> 42 <td>{position}</td> 43 </tr> 44 ))} 45 </tbody> 46 </table> 47 </div> 48 ) 49} 50 51export default EditableTable

Step 02: Editable Table Data

The primary option that comes to mind for making editable table data is wrapping the td tag into the input tag. Let us do this first.

jsx
1<tbody> 2 {employeeData.map(({ employeeId, name, email, position }) => ( 3 <tr key={employeeId}> 4 <td> 5 <input 6 name="name" 7 value={name} 8 type="text" 9 onChange={onChangeInput} 10 placeholder="Type Name" 11 /> 12 </td> 13 <td> 14 <input 15 name="email" 16 value={email} 17 type="text" 18 onChange={onChangeInput} 19 placeholder="Type Email" 20 /> 21 </td> 22 <td> 23 <input 24 name="position" 25 type="text" 26 value={position} 27 onChange={onChangeInput} 28 placeholder="Type Position" 29 /> 30 </td> 31 </tr> 32 ))} 33</tbody>

But here is one problem…

Now observe that the editable text field is not yet functional. In the next step, we will make it functional.

Step 03: Changing Table data Value

We have to write an onChange Handler Function for changing the table data value. This function is to handle the Input tag.

jsx
1import { useState } from 'react' 2import './index.css' 3 4const data = [ 5 { 6 employeeId: '01', 7 name: 'John Doe', 8 email: 'johndoe@email.com', 9 position: 'Frontend Developer', 10 }, 11 { 12 employeeId: '02', 13 name: 'Sara', 14 email: 'sara@email.com', 15 position: 'HR Executive', 16 }, 17 { 18 employeeId: '03', 19 name: 'Mike', 20 email: 'mike@email.com', 21 position: 'Backend Developer', 22 }, 23] 24 25const EditableTable = () => { 26 const [employeeData, setEmployeeData] = useState(data) 27 28 const onChangeInput = (e, employeeId) => { 29 const { name, value } = e.target 30 console.log('name', name) 31 console.log('value', value) 32 console.log('employeeId', employeeId) 33 34 const editData = employeeData.map((item) => 35 item.employeeId === employeeId && name ? { ...item, [name]: value } : item, 36 ) 37 38 console.log('editData', editData) 39 40 setEmployeeData(editData) 41 } 42 43 return ( 44 <div className="container"> 45 <h1 className="title">ReactJS Editable Table</h1> 46 <table> 47 <thead> 48 <tr> 49 <th>Name</th> 50 <th>Email</th> 51 <th>Position</th> 52 </tr> 53 </thead> 54 <tbody> 55 {employeeData.map(({ employeeId, name, email, position }) => ( 56 <tr key={employeeId}> 57 <td> 58 <input 59 name="name" 60 value={name} 61 type="text" 62 onChange={(e) => onChangeInput(e, employeeId)} 63 placeholder="Type Name" 64 /> 65 </td> 66 <td> 67 <input 68 name="email" 69 value={email} 70 type="text" 71 onChange={(e) => onChangeInput(e, employeeId)} 72 placeholder="Type Email" 73 /> 74 </td> 75 <td> 76 <input 77 name="position" 78 type="text" 79 value={position} 80 onChange={(e) => onChangeInput(e, employeeId)} 81 placeholder="Type Position" 82 /> 83 </td> 84 </tr> 85 ))} 86 </tbody> 87 </table> 88 </div> 89 ) 90} 91 92export default EditableTable

Now the main part,

jsx
1const onChangeInput = (e, employeeId) => { 2 const { name, value } = e.target 3 console.log('name', name) 4 console.log('value', value) 5 console.log('employeeId', employeeId) 6 7 const editData = employeeData.map((item) => 8 item.employeeId === employeeId && name ? { ...item, [name]: value } : item, 9 ) 10 11 console.log('editData', editData) 12 13 setEmployeeData(editData) 14}

You can see we have multiple consoles in this function, to debug that are we getting correct values.

Then we map over employeeData and check if the current employeeId equals to the id, and name also matches with name of input, we will change only that input values, the rest of the values will be the same.

To complete, we will setState and pass editData to it.

Read More On This

The article "Reusable Input Component in React" will help you understand how to build an input component in React with TypeScrip.

For insights on effectively updating objects within an array, refer to the article "How to Update an Array of Objects".

These resources will help you deepen your understanding of this topic.

Congrats, you have created the table with editable text fields.

What about making it stylish and interactive?

Styling the Editable Text fields in the Table

For interactivity, I added the hover effect, on a text field, so user can know he can interact with it.

We also removed the default border and styled input focus state, to make the user experience smooth.

Complete Code

jsx
1import { useState } from 'react' 2import './index.css' 3 4const data = [ 5 { 6 employeeId: '01', 7 name: 'John Doe', 8 email: 'johndoe@email.com', 9 position: 'Frontend Developer', 10 }, 11 { 12 employeeId: '02', 13 name: 'Sara', 14 email: 'sara@email.com', 15 position: 'HR Executive', 16 }, 17 { 18 employeeId: '03', 19 name: 'Mike', 20 email: 'mike@email.com', 21 position: 'Backend Developer', 22 }, 23] 24 25const EditableTable = () => { 26 const [employeeData, setEmployeeData] = useState(data) 27 28 const onChangeInput = (e, employeeId) => { 29 const { name, value } = e.target 30 31 const editData = employeeData.map((item) => 32 item.employeeId === employeeId && name ? { ...item, [name]: value } : item, 33 ) 34 35 setEmployeeData(editData) 36 } 37 38 return ( 39 <div className="container"> 40 <h1 className="title">ReactJS Editable Table</h1> 41 <table> 42 <thead> 43 <tr> 44 <th>Name</th> 45 <th>Email</th> 46 <th>Position</th> 47 </tr> 48 </thead> 49 <tbody> 50 {employeeData.map(({ employeeId, name, email, position }) => ( 51 <tr key={employeeId}> 52 <td> 53 <input 54 name="name" 55 value={name} 56 type="text" 57 onChange={(e) => onChangeInput(e, employeeId)} 58 placeholder="Type Name" 59 /> 60 </td> 61 <td> 62 <input 63 name="email" 64 value={email} 65 type="text" 66 onChange={(e) => onChangeInput(e, employeeId)} 67 placeholder="Type Email" 68 /> 69 </td> 70 <td> 71 <input 72 name="position" 73 type="text" 74 value={position} 75 onChange={(e) => onChangeInput(e, employeeId)} 76 placeholder="Type Position" 77 /> 78 </td> 79 </tr> 80 ))} 81 </tbody> 82 </table> 83 </div> 84 ) 85} 86 87export default EditableTable

CSS

css
1@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;600&display=swap'); 2 3body { 4 box-sizing: border-box; 5 color: #220f5f; 6 font-family: 'Poppins', sans-serif; 7} 8 9.container { 10 width: 100%; 11 max-width: 800px; 12 padding: 0 10px; 13 margin: 0 auto; 14 margin-top: 70px; 15} 16 17.title { 18 text-align: center; 19 font-size: 26px; 20 margin-bottom: 30px; 21} 22 23table { 24 border-collapse: collapse; 25 width: 100%; 26} 27 28tr th { 29 font-size: 18px; 30 padding: 12px; 31 border: 1px solid #eeeeee; 32 text-align: left; 33 background-color: rgba(217, 221, 146, 0.2); 34} 35 36tr td { 37 border: 1px solid #eeeeee; 38 text-align: left; 39} 40 41input { 42 font-size: 16px; 43 background-color: transparent; 44 border: none; 45 width: 91%; 46 padding: 12px 12px; 47 font-family: 'Poppins', sans-serif; 48} 49 50input:hover { 51 background-color: #fffaf3; 52} 53 54input:focus { 55 outline: 1px solid #ccc; 56 border: 1px solid #ccc; 57}

I hope you find this article valuable.

ShareTwitterLinkedIn

Written by

Abdul Basit

Frontend developer passionate about JavaScript, React, and building great web experiences. Writing about web development to help developers level up their skills.

Continue reading