Need to create a drag-and-drop sortable table for your project? We can actually do it with pure HTML and Javascript within minutes, we don’t even need to load any of those “bloated frameworks” – 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
DRAG & DROP SORTABLE TABLE DEMO
Breed | Size |
---|---|
Akita | Large |
Beagle | Small |
Chihuahua | Small |
Dalmatian | Medium |
Eurasier | Medium |
Foxhound | Large |
German Shepherd | Large |
Hovawart | Large |
Irish Setter | Large |
Shiba Inu | Small |
Go ahead, drag and drop the rows to sort. Of course, the header row is not sortable…
P.S. If you are using a touch device, this may not work. See “note for touch devices” below.
PART 1) THE HTML – A REGULAR TABLE
<table id="demo">
<tr>
<th>Breed</th> <th>Size</th>
</tr>
<tr>
<td>Akita</td> <td>Large</td>
</tr>
<tr>
<td>Beagle</td> <td>Small</td>
</tr>
<tr>
<td>Chihuahua</td> <td>Small</td>
</tr>
<tr>
<td>Dalmatian</td> <td>Medium</td>
</tr>
<tr>
<td>Eurasier</td> <td>Medium</td>
</tr>
<tr>
<td>Foxhound</td> <td>Large</td>
</tr>
<tr>
<td>German Shepherd</td> <td>Large</td>
</tr>
<tr>
<td>Hovawart</td> <td>Large</td>
</tr>
<tr>
<td>Irish Setter</td> <td>Large</td>
</tr>
<tr>
<td>Shiba Inu</td> <td>Small</td>
</tr>
</table>
First, start with creating your table. Yes, there’s “nothing special” here. It’s just a good old HTML table.
PART 2) THE JAVASCRIPT – DRAG & DROP MECHANISM
window.addEventListener("load", () => {
// (PART A) GET TABLE ROWS, EXCLUDE HEADER ROW
var all = document.querySelectorAll("#demo tr:not(:first-of-type)");
// (PART B) "CURRENT ROW BEING DRAGGED"
var dragged;
// (PART C) DRAG-AND-DROP MECHANISM
for (let tr of all) {
// (C1) ROW IS DRAGGABLE
tr.draggable = true;
// (C2) ON DRAG START - SET "CURRENTLY DRAGGED" & DATA TRANSFER
tr.ondragstart = e => {
dragged = tr;
e.dataTransfer.dropEffect = "move";
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.setData("text/html", tr.innerHTML);
};
// (C3) PREVENT DRAG OVER - NECESSARY FOR DROP TO WORK
tr.ondragover = e => e.preventDefault();
// (C4) ON DROP - "SWAP ROWS"
tr.ondrop = e => {
e.preventDefault();
if (dragged != tr) {
dragged.innerHTML = tr.innerHTML;
tr.innerHTML = e.dataTransfer.getData("text/html");
}
};
// (C5) COSMETICS - HIGHLIGHT ROW "ON DRAG HOVER"
tr.ondragenter = () => tr.classList.add("hover");
tr.ondragleave = () => tr.classList.remove("hover");
tr.ondragend = () => {
for (let r of all) { r.classList.remove("hover"); }
};
}
});
- On window load, get all the table rows. Exclude the first header row.
- Create a
dragged
flag to “hold” the current row that is being dragged. - Loop through the rows, and set the actual drag and drop mechanics.
- (C1) Set the row as “draggable”.
- (C2) On drag start, we “mark the source row” in
draggable
and set itsinnerHTML
in “data transfer”. - (C3) Prevent the browser’s default action on drag over. This is necessary for the drop action (C4) to work properly.
- (C4) On dropping the dragged row, we “exchange” the
innerHTML
of the source and target rows. - (C5) That’s about it, this section is purely for cosmetics. Highlight the row as
dragged
hovers over it.
PART 3) THE CSS – COSMETICS
/* (PART A) ENTIRE TABLE */
#demo { width: 400px; border-collapse: collapse; }
#demo tr:nth-child(odd) { background: #f2f2f2; }
#demo td, #demo th {
text-align: left; padding: 10px;
border: 1px solid #ccc;
}
#demo th { color: #fff; background: #51759a; }
/* (PART B) ON DRAG HOVER */
#demo tr.hover { background: #eff70d; }
Finally, just some cosmetics. Feel free to style the table however you wish.
THE END – A NOTE FOR TOUCH DEVICES
That’s all for this short tutorial and sharing. But please take note, draggable
is still not properly implemented on touch devices at the time of writing. Master Coffee knows this is disgusting, but it is what it is. Load a polyfill such as DragDropTouch if you want to support touch devices.
CHEAT SHEET