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.
[javascript]
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);
[/javascript]
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.
Our sorter snippet will sort a list (by price) with such a markup:
[html]
<div id="grid">
<div class="level">
<div>Alferd Penyworth</div>
<div>alfred@batman.com</div>
<div class="price">199</div>
</div>
<div class="level">
<div>Jane Vanda</div>
<div>jane@vanda.org<div>
<div class="price">399</div>
</div>
<div class="level">
<div>John Doe</div>
<div>john.doe@gmail.com</div>
<div class="price">99</div>
</div>
</div>
[/html]
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.