Simple and Lightweight JavaScript Table/Grid/List Sorter

This is more of a snippet extracted from one of my recent projects where I had to sort a list/grid of div’s. Yeah, I didn’t use tables for tabular data this time, but plain divs, although this snippet will work just fine with html table rows too.

var sortGrid = function (grid, levels, order) {
  var levels = Array.prototype.splice.call(levels, 0);

  var compare = function (a, b) {
    var el1 = a.querySelector('.price')
      , el2 = b.querySelector('.price');
    
    var v1 = parseFloat( el1.innerHTML )
      , v2 = parseFloat( el2.innerHTML );
    
    if (!v1 || !v2) {
      // assuming its just text
      v1 = el1.innerHTML.trim().toLowerCase();
      v2 = el2.innerHTML.trim().toLowerCase();
    }

    return (v1 > v2) ? 1 : ((v1 < v2) ? -1 : 0);
  };
  
  levels.sort(compare);
  if (order === 'desc') {
    levels.reverse();
  }

  grid.innerHTML = '';
  levels.forEach(function (level) {
    grid.appendChild(level);
  });
};

var grid = document.querySelector('#grid');
var levels = document.querySelectorAll('#grid .level');
var order = 'asc'; // or 'desc'

sortGrid(grid, levels, order);

We’re basically converting our array-like object (levels) of DOM elements to a pure array and sort it based on the value inside the DOM element with price class using Array.prototype.sort.

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

Our sorter snippet will sort a list (by price) with such a markup:

<div id="grid">
  <div class="level">
    <div>Alferd Penyworth</div>
    <div>[email protected]</div>
    <div class="price">199</div>
  </div>
  <div class="level">
    <div>Jane Vanda</div>
    <div>[email protected]<div>
    <div class="price">399</div>
  </div>
  <div class="level">
    <div>John Doe</div>
    <div>[email protected]</div>
    <div class="price">99</div>
  </div>
</div>

Now my requirement was to just sort by the price column (cells) but you can add a header denoting each column and bind click events to them for sorting or just make it work with any other column by specifying new classes. You’ll need to get the index of the clicked header cell and then get the contents of the cell with the same index in all the rows (inside the sort compare function) instead of using querySelector(selector) like I did.

Getting “clicked” index is easy when using html tables with the cellIndex property and then sort the rows (tr) by the cell (td/th) with the same index accessed via tr_ob.cells.item(index). When not using tables, getting the index is slightly tricky as you’ve to keep track of them using a closure. Even better, use jQuery’s index!

The snippet above was initially a fork of this neat experiment.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

Leave a Reply

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