Welcome to a tutorial on how to create an editable HTML table. Well, creating an editable table is quite literally adding a contentEditable
property into the cell <td>
on a double click. But it still requires quite some bits of code – Read on for an example!
TABLE OF CONTENTS
DOWNLOAD & DEMO
Here is the download link to the example code, so you don’t have to copy-paste everything.
EXAMPLE CODE DOWNLOAD
Click here to download. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
EDITABLE TABLE DEMO
Name | |
---|---|
Job Doe | job@doe.com |
Joe Doe | joe@doe.com |
Joi Doe | joi@doe.com |
Jon Doe | jon@doe.com |
Joy Doe | joy@doe.com |
SORRY FOR THE ADS...
But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.
Buy Me A Coffee Code Boxx eBooks
EDITABLE HTML TABLE
All right, let us now get into more details about how the editable HTML table works.
TUTORIAL VIDEO
PART 1) THE HTML
<table class="editable">
<!-- (A) HEADER -->
<thead>
<tr>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<!-- (B) DATA -->
<tbody>
<tr>
<td>Job Doe</td>
<td>job@doe.com</td>
</tr>
<tr>
<td>Joe Doe</td>
<td>joe@doe.com</td>
</tr>
<tr>
<td>Joi Doe</td>
<td>joi@doe.com</td>
</tr>
<tr>
<td>Jon Doe</td>
<td>jon@doe.com</td>
</tr>
<tr>
<td>Joy Doe</td>
<td>joy@doe.com</td>
</tr>
</tbody>
</table>
Well, nothing special here. This is just a “normal HTML table” with an editable
CSS class.
PART 2) THE JAVASCRIPT
2A) DOUBLE-CLICK TO “EDIT CELL”
// (A) INITIALIZE - DOUBLE CLICK TO EDIT CELL
window.addEventListener("DOMContentLoaded", () => {
for (let cell of document.querySelectorAll(".editable td")) {
cell.ondblclick = () => editable.edit(cell);
}
});
The magic of turning the “normal HTML table” into an “editable HTML table” lies in Javascript. The very first thing we need to do is to attach a double-click listener to all table cells <td>
.
2B) “CONVERT” CELL TO EDITABLE FIELD
var editable = {
// (B) PROPERTIES
selected : null, // current selected cell
value : "", // current selected cell value
// (C) "CONVERT" TO EDITABLE CELL
edit : cell => {
// (C1) REMOVE "DOUBLE CLICK TO EDIT"
cell.ondblclick = "";
// (C2) EDITABLE CONTENT
cell.contentEditable = true;
cell.focus();
// (C3) "MARK" CURRENT SELECTED CELL
cell.classList.add("edit");
editable.selected = cell;
editable.value = cell.innerHTML;
// (C4) PRESS ENTER/ESC OR CLICK OUTSIDE TO END EDIT
window.addEventListener("click", editable.close);
cell.onkeydown = evt => {
if (evt.key=="Enter" || evt.key=="Escape") {
editable.close(evt.key=="Enter" ? true : false);
return false;
}
};
},
// ...
};
This is a little long-winded, but keep calm and look closely. On double-clicking on a cell, all this essentially does is:
- (C1) Remove “double click” to edit cell… Since it is already in “edit mode”.
- (C2) Set
contentEditable
on the selected cell and focus on it. - (C3) Set the “currently editing cell” into
editable.selected
, and its current value intoeditable.value
. - (C4) There are 2 ways to end the “edit mode”.
- Click outside of
editable.selected
. - By pressing “enter” or “escape” within
editable.selected
.
- Click outside of
2C) END “EDIT MODE”
// (D) END "EDIT MODE"
close : evt => { if (evt.target != editable.selected) {
// (D1) CANCEL - RESTORE PREVIOUS VALUE
if (evt === false) {
editable.selected.innerHTML = editable.value;
}
// (D2) REMOVE "EDITABLE"
window.getSelection().removeAllRanges();
editable.selected.contentEditable = false;
// (D3) RESTORE CLICK LISTENERS
window.removeEventListener("click", editable.close);
let cell = editable.selected;
cell.onkeydown = "";
cell.ondblclick = () => editable.edit(cell);
// (D4) "UNMARK" CURRENT SELECTED CELL
editable.selected.classList.remove("edit");
editable.selected = null;
editable.value = "";
// (D5) DO WHATEVER YOU NEED
if (evt !== false) {
console.log(cell.innerHTML);
// check value?
// send value to server?
// update calculations in table?
}
}}
Lastly, this will deal with ending the “edit mode” – When the user clicks outside of the cell, or by pressing ENTER/ESCAPE
.
- (D1) When the user hits escape to “cancel edit” – Restore to the cell’s previous value.
- (D2) Remove the
contentEditable
property, and “restore” it to a normal<td>
. - (D3) Remove “click to end edit mode” listeners, and reattach the “double click to edit cell”.
- (D4) Clear the “currently editing cell”.
- (D5) This is pretty much up to you to complete. Do whatever is required in your own project.
PART 3) THE CSS
/* (A) ENTIRE PAGE */
* {
font-family: Arial, Helvetica, sans-serif;
box-sizing: border-box;
}
/* (B) EDITABLE TABLE */
.editable {
border-collapse: collapse;
}
.editable th, .editable td {
text-align: left;
padding: 15px;
}
.editable tbody tr:nth-child(even) {
background: #f2f2f2;
}
.editable td.edit {
background: #f8ff88;
}
Not important actually. Just some cosmetics to make things look better.
EXTRAS
That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.
HOW TO TIE CELL VALUE TO AN ID?
- Simply add a custom data attribute to the table cells
<td data-id="123">
. - Get the cell value and custom data in Javascript –
if (evt !== false) { console.log(cell.innerHTML, cell.dataset.id); }
CLICK OUTSIDE CELL TO CANCEL
// (C4) PRESS ENTER/ESC OR CLICK OUTSIDE TO END EDIT
window.addEventListener("click", () => editable.close(false));
This may make more sense for mobile devices “without an escape key”. Well, you decide.
COMPATIBILITY CHECKS
- Arrow Functions – CanIUse
- Content Editable – CanIUse
This example will work on all modern browsers.
LINKS & REFERENCES
- Sortable HTML Table – Code Boxx
- HTML Custom Data Attribute – MDN
THE END
Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!
Hi ! And thanks for the amazing work.
I may be wrong BUT when using your example on code pen, the final console.log outputs the value even if there is no change in the value).
That is correct. Editable does not have the same behavior as onchange. So if you want to “detect value changed” or “revert to old value”, you will have to do some changes on your own… If not, I will keep as this a possible future update. Good luck!
Hello! Thanks for this blog post, awesome work. I have a quick question though, I am fairly new to JS programming but I was wondering what its called when you add properties to a variable like you do B-D in the code. I’ve never seen development like that and wondering what that’s called so I can find more information.
Specifically lines like “edit : cell => {” Are you adding a function to a variable? How are you able to do all of that within a variable definition?
Any info on this would be great, again thanks for the great content!
That is called an arrow function, a “lazy shorthand” for defining functions.
So pretty much in “full form” –
editable.edit = function (cell) { ... }
Hi, Thank you for your code. I am making a code using your code, BUT I don’t know how to make a “D5” part. How can I save the changed value to database?
IF you give me a simple example, thank you of it. Thank you!
Study basic AJAX, form submission, and how to work with databases on your own. Good luck.
https://code-boxx.com/save-form-php-mysql/
https://code-boxx.com/faq/#help “Answers all over the Internet”
Hi.. Thanks for the example. How can we do the same in typscript (.ts file) ?. I’m completely nw to angular.
Technically speaking, Typescript is just “strict mode strongly typed Javascript”. If you want to turn this into an Angular component, you can. The best I can explain in a single line – Learn strict mode Javascript, and what strongly-typed languages mean. Good luck.
https://code-boxx.com/faq/#help “Answers all over the Internet”
I APPRECIATE THE BLOG AND THE CODE, BUT ONE OF THE UNZIPPED CODE FILES (JS) WON’T OPEN DUE TO A COMPILING(?) ERROR, AND YOUR WEBPAGES CAN’T BE COPIED. I’M NOT SURE IF YOU’RE AWARE OF THIS. IT MIGHT MAKE PEOPLE AVOID THIS WEBSITE. JUST THOUGHT YOU WOULD LIKE TO KNOW.
KEN ROBINSON
1) The demo on this page works on Chrome, Firefox, Opera, Edge, and even Android Chrome.
2) I don’t “disable copy”, nor do any of those “block people with adblock”.
3) If you want to “double click to edit JS file” – Follow up with your own studies on “set default application for file type”.
No idea what you are talking about, but your CAPS LOCK IS BROKEN. Just thought you would like to know. Good luck. 😆
https://code-boxx.com/faq/#notwork