Once upon a time, a student wanted to create an editable table. She then “hides” a text input in every cell that will only “activate” on double click… While it works, there is an easier way with contentEditable = true
. Let Master Coffee show you how – Let’s go.
CODE DOWNLOAD
I have released this under the MIT license, feel free to use it in your own project – Personal or commercial. Some form of credits will be nice though. 🙂
VIDEO TUTORIAL
EDITABLE TABLE DEMO
Coffee | Strength |
---|---|
Latte | Weak |
Cappuccino | Weak |
Cold Brew | Medium |
Espresso | Strong |
Ristretto | Strong |
- Double-click on a cell to edit… Table headers are not editable.
- Click on anywhere outside of the cell or press “enter” to end.
- Press “escape” to cancel.
1) THE HTML
<table class="editable">
<!-- (PART A) HEADER -->
<tr> <th>Coffee</th> <th>Strength</th> </tr>
<!-- (PART B) DATA -->
<tr> <td>Latte</td> <td>Weak</td> </tr>
<tr> <td>Cappuccino</td> <td>Weak</td> </tr>
<tr> <td>Cold Brew</td> <td>Medium</td> </tr>
<tr> <td>Espresso</td> <td>Strong</td> </tr>
<tr> <td>Ristretto</td> <td>Strong</td> </tr>
</table>
For the HTML, this is just a “regular table”. Just make sure that header cells are <th>
and “normal cells” are <td>
.
2) THE JAVASCRIPT
var editable = {
// (PART A) FLAGS
ccell : null, // current editing cell
cval : null, // current cell value
// (PART B) EDIT CELL
edit : cell => {
// (B1) "SAVE" SELECTED CELL
editable.ccell = cell;
editable.cval = cell.innerHTML;
// (B2) SET EDITABLE
cell.classList.add("edit");
cell.contentEditable = true;
cell.focus();
// (B3) LISTEN TO END EDIT
cell.onblur = editable.done;
cell.onkeydown = e => {
if (e.key=="Enter") { editable.done(); }
if (e.key=="Escape") { editable.done(1); }
};
},
// (PART C) EXIT EDIT CELL
done : discard => {
// (C1) REMOVE LISTENERS
editable.ccell.onblur = "";
editable.ccell.onkeydown = "";
// (C2) STOP EDIT
editable.ccell.classList.remove("edit");
editable.ccell.contentEditable = false;
// (C3) DISCARD CHANGES
if (discard===1) { editable.ccell.innerHTML = editable.cval; }
// (C4) DO WHATEVER YOU WANT
if (editable.ccell.innerHTML != editable.cval) {
/* VALUE CHANGED */
console.log(editable.ccell.innerHTML);
}
}
};
// (PART D) DOUBLE CLICK TO EDIT CELL
window.addEventListener("load", () => {
for (let td of document.querySelectorAll(".editable td")) {
td.addEventListener("dblclick", () => editable.edit(td));
}
});
Some beginners may get a panic attack, but keep calm and trace in this manner:
- (D) On window load, attach double-click every table cell to call
editable.edit()
. - (B) Transform the selected cell into an “editable cell” on double-click.
- (B1) Set the selected cell into
ccell
, and its original content intocval
. - (B2) No need to “insert hidden text field”, just set the selected cell to
contentEditable = true
. - (B3) 3 ways to end “edit mode” – Click anywhere outside the cell, press enter, or press escape.
- (B1) Set the selected cell into
- (C) To exit “edit mode” on the selected cell.
- (C1) Remove the “click outside” and “press enter/escape” to end.
- (C2) Reset back to non-editable cell –
contentEditable = false
. - (C3) On pressing escape only, cancel and restore the previous value.
- (C4) Do whatever you need, if the cell value has changed.
3) THE CSS
/* (PART A) WHOLE PAGE */
* {
font-family: Arial, Helvetica, sans-serif;
box-sizing: border-box;
}
body { background: #f2f2f2; }
/* (PART B) EDITABLE TABLE */
table.editable {
border-collapse: collapse;
background: #fff;
}
table.editable th, table.editable td {
text-align: left;
padding: 20px;
border: 1px solid #ccc;
}
table.editable td.edit { background: #fbff5b; }
Not important. Just some cosmetics, and highlight the selected cell on double-click.
THE END – ADD ASSOCIATED DATA TO CELLS
That’s all for this short tutorial and sharing. One last extra bit for the beginners – If you want to add more data to the cells, such as an ID:
- Add data to the cell –
<td data-id="123">
- Get the attached data in (C4) –
editable.ccell.dataset.id
.
CHEAT SHEET