Simple Sortable Table With HTML Javascript (Free Download)

Welcome to a tutorial on how to create a simple sortable table with Javascript. So you have an array or HTML table that needs some sortable action? Sadly, there is no way we can do it with just pure HTML. We need to define data arrays and do array sorting in Javascript instead – This guide will walk you through the exact steps on how to do it, read on to find out!

 

 

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.

 

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

 

SORTABLE TABLE ON AN EXISTING TABLE

1-existing.html
<!-- (A) JS + CSS -->
<link rel="stylesheet" href="sortable.css">
<script src="sortable.js"></script>
 
<!-- (B) TABLE : NEEDS PROPER THEAD/TBODY -->
<table id="demoA">
  <thead>
    <tr>
      <td>Fruit</td>
      <td>Color</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Durian</td>
      <td>Green</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
    </tr>
    <tr>
      <td>Apple</td>
      <td>Red</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Red</td>
    </tr>
    <tr>
      <td>Blueberry</td>
      <td>Blue</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
    </tr>
  </tbody>
</table>
 
 <!-- (C) INITIALIZE -->
<script>
sortable(document.getElementById("demoA"));
</script>
Fruit Color
Durian Green
Orange Orange
Apple Red
Grape Red
Blueberry Blue
Pear Green
  1. Load the Javascript sortable.js, the CSS is optional.
  2. Create your HTML table as usual. Just make sure that it has a proper <thead> and <tbody> section.
  3. Call sortable(HTML TABLE) to turn it into a sortable table.

 

 

SORTABLE TABLE WITH OBJECT DATA

2-data-object.html
<!-- (B) EMPTY TABLE -->
<table id="demoB"></table>
 
<!-- (C) INITIALIZE -->
<script>
sortable(document.getElementById("demoB"), {
  ID : [44, 11, 7, 5, 2],
  Name : ["John Doe", "Jane Doe", "Aaron Doe", "Zoe Doe", "Derrick Doe"],
  Color : ["Red", "Green", "Blue", "White", "Red"]
});
</script>

Yes, it’s the same sortable(), except that we pass in an object data in the second parameter.

P.S. The object must be in the format of { HEAD : [ROWS], HEAD : [ROWS], ETC... }

 

SORTABLE TABLE JAVASCRIPT

With that, let us now get into more details of how the sortable table work in this section – This is for you guys who want to “deep customize” it.

 

TUTORIAL VIDEO

 

PART 1) ADDING FLAGS TO THE TABLE

sorta.js
function sortable (instance, data) {
  // (A) FLAGS
  instance.sBy = null;        // sort by this column
  instance.sDirection = true; // ascending/descending order
  instance.sOrder = [];       // calculated sort order
 
  // ...
}

The entire Javascript file only has a function sortable(), which you have seen in the above demo. A quick reminder on the parameters:

  • instance The HTML table itself.
  • data Optional, object data.

The first thing we do is to initialize the sort mechanics by adding flags to the HTML table. Yes, beginners, we can add variables to HTML elements in modern Javascript.

  • sBy Sort by which column.
  • sDirection Sort in ascending (true) or descending (false) order.
  • sOrder The calculated sort order.

 

 

PART 2) SORT FUNCTION

sorta.js
// (B) SORT FUNCTION
instance.sort = selected => {
  // (B1) UPDATE SORT FLAGS
  if (instance.sBy == selected.innerHTML) {
    instance.sDirection = !instance.sDirection;
  } else {
    instance.sBy = selected.innerHTML;
    instance.sDirection = true;
  }
 
  // (B2) UPDATE CSS OF HEADER CELLS
  for (let c of instance.head.rows[0].cells) {
    c.classList.remove("sortup");
    c.classList.remove("sortdown");
    if (c == selected) {
      c.classList.add((instance.sDirection ? "sortup" : "sortdown"));
    }
  }
 
  // (B3) MAP OUT DATA OF THE SELECTED COLUMN
  // I.E. WE NEED TO RETAIN THE INDEX POSITIONS WHILE SORTING
  let map = data[selected.innerHTML].map((v, i) => { return { i: i, v: v }; });
 
  // (B4) SORT ARRAY
  if (instance.sDirection) {
    map.sort((a, b) => {
      if (a.v > b.v) { return 1; }
      if (a.v < b.v) { return -1; }
      return 0;
    });
  } else {
    map.sort((a, b) => {
      if (a.v < b.v) { return 1; }
      if (a.v > b.v) { return -1; }
      return 0;
    });
  }
 
  // (B5) REDRAW TABLE WITH NEW SORT ORDER
  instance.sOrder = [];
  for (let idx in map) { instance.sOrder.push(map[idx].i); }
  delete(map); instance.draw();
};

Yikes, the next piece of confusion is called “sort”. Not going to explain this line-by-line, but the essentials are:

  • As above. Keep in mind that the table data is kept in the format of { HEAD : [ITEM, ITEM, ITEM] }.
  • We will not mess with data directly, but calculate the sort order for [ITEM, ITEM, ITEM] separately in sOrder.
  • When the user clicks on a header cell to sort:
    • (B1) We set the “sort by this column” sBy and sort direction sDirection.
    • (B3)  Create a temporary var map with both the index and value of the items – var map = [{i:INDEX, v:ITEM}, {i:INDEX, v:ITEM}].
    • (B4) Sort the map.
    • (B5) Loop through map, extract only the index into sOrder.

 

 

PART 3) DRAW TABLE ROWS

sorta.js
// (C) DRAW HTML TABLE
instance.draw = () => {
  // (C1) REMOVE OLD SORT ORDER
  instance.body.innerHTML = "";
 
  // (C2) DRAW NEW SORT ORDER
  let r, c;
  for (let i of instance.sOrder) {
    r = instance.body.insertRow();
    for (let key in data) {
      c = r.insertCell();
      c.innerHTML = data[key][i];
    }
  }
};

Once we have the sort order, simply loop through sOrder and draw the table rows.

 

PART 4) READ EXISTING TABLE

sorta.js
// (D) ADAPT DATA FROM EXISTING TABLE
if (data==undefined) {
  // (D1) GET TABLE SECTIONS
  instance.head = instance.querySelector("thead");
  instance.body = instance.querySelector("tbody");
 
  // (D2) GET DATA FROM HEADER
  data = {}; keys = [];
  for (let c of instance.head.rows[0].cells) {
    data[c.innerHTML] = [];
    keys.push(c.innerHTML);
  }
 
  // (D3) GET DATA FROM BODY
  for (let r of instance.body.rows) { for (let i=0; i<r.cells.length; i++) {
    data[keys[i]].push(r.cells[i].innerHTML);
  }}
  delete(keys);
}

Remember the data parameter? For existing tables, we simply run through the table and adapt the data.

 

 

PART 5) BUILD SORTABLE TABLE FROM OBJECT

sorta.js
// (E) DRAW SORTABLE TABLE FROM OBJECT
else {
  // (E1) CREATE TABLE SECTIONS
  instance.head = instance.createTHead();
  instance.body = instance.createTBody();
 
  // (E2) HEADER CELLS
  let r = instance.head.insertRow();
  r = instance.head.rows[0];
  for (let key in data) {
    let c = r.insertCell();
    c.innerHTML = key;
  }
 
  // (E3) DEFAULT SORT ORDER & DRAW BODY
  for (let i=0; i<data[Object.keys(data)[0]].length; i++) { instance.sOrder.push(i); }
  instance.draw();
}

If an object data is specified, we simply build the HTML from it.

 

PART 6) CSS CLASS & CLICK TO SORT

sorta.js
// (F) CLICK ON HEADER CELL TO SORT
instance.classList.add("sorta");
  for (let r of instance.head.rows) { for (let c of r.cells) {
  c.onclick = () => instance.sort(c);
}} 

This final part should be self-explanatory. We attach the “click to sort” on all header cells.

 

 

EXTRAS

That’s all for this project, and here is a small section on some extras and links that may be useful to you.

 

LIMITATIONS & PERFORMANCE

This sortable table relies on ARRAY.sort() – It should work pretty well and fast with most modern computers these days… But yep, it is not the most effective way to do sorting, and you will probably get hit with performance issues with large datasets.

 

NO “ERROR CHECKING”

Please make sure that your dataset and number of columns are correct on your own. I have contemplated adding an “auto check and fix”, but came to a simple conclusion:

  • Checking massive datasets takes resources, it is simply not efficient to do so for the sake of “dummy proofing”.
  • This is a “simple sortable table” tutorial, not “how to automatically fix your screw-up”.
  • As a developer (or even as a user), you are responsible for the integrity of your own datasets.
  • If there is a missing column or extra columns – Only you know what needs to be fixed.

 

COMPATIBILITY CHECKS

All the required features are well-supported on modern browsers.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

3 thoughts on “Simple Sortable Table With HTML Javascript (Free Download)”

  1. Hello, I am JS enthusiast but not a pro.
    Well done but it crash when more column in bodythat in header (well ok that’s not supposed to be). Correction to allow more body column that header 🙂

    // (D3) GET DATA FROM BODY
    var cx=0;
    for (let r of instance.body.rows) { for (let i=0; i<r.cells.length; i++) {
      if (keys[i]) {
        data[keys[i]].push(r.cells[i].innerHTML);
      } else {
        newColName="_"+cx;
        keys[i]=(newColName); 
        if (! Array.isArray(data[cx])){ data[newColName]=[]; }
        data[newColName][i]=(r.cells[i].innerHTML);	
        cx++;
      }
    }}
    delete(keys);
    1. Thanks for sharing. I will assume you mean “when the number of columns in the head and body doesn’t match”. I will add a check and throw errors in the future, but not “automatically fix it” by generating empty cells – Users should verify the data by themselves.

Leave a Comment

Your email address will not be published. Required fields are marked *