(function($) {
$.fn.sortable = function() {
this.find('thead').on('click', 'th', function(e) {
var columnIndex = $(this).index();
var $tbody = $(this).closest('table').find('tbody');
var rows = $tbody.children().detach().get();
rows.sort(function(left, right) {
var $left = $(left).children().eq(columnIndex);
var $right = $(right).children().eq(columnIndex);
return $left.text().localeCompare($right.text());
});
$tbody.append(rows);
});
return this;
};
$.fn.renderTable = function(data) {
var fields = Object.keys(data[0]);
return this.renderTableHeaders(fields).renderTableRows(fields, data);
};
$.fn.renderTableHeaders = function(fields) {
return this.append($.renderTableHeaders(fields));
}
$.fn.renderTableRows = function(fields, data) {
return this.append($.renderTableRows(fields, data));
};
$.tableFromJson = function(data) {
return $('<table>').renderTable(data);
};
$.renderTableHeaders = function(fields) {
return $('<thead>').append($('<tr>').append(fields
.map(field => $('<th>').text(field))));
};
$.renderTableRows = function(fields, data) {
return $('<tbody>').append(data
.map((rec, row) => $('<tr>').append(fields
.map((field, col) => $('<td>').text(rec[field])))));
};
$.bindableTable = function(data, sortable) {
var $table = $.tableFromJson(data).addClass('bindable');
if (sortable) {
$table.dataRef = data;
$table.addClass('sortable').find('thead').on('click', 'th', function(e) {
var dataIndex = $(this).text();
$table.dataRef.sort(function (a, b) {
var left = new String(a[dataIndex]);
var right = new String(b[dataIndex]);
return left.localeCompare(right);
});
var fields = Object.keys($table.dataRef[0]);
$table.find('tbody').replaceWith($.renderTableRows(fields, $table.dataRef));
});
}
return $table;
};
})(jQuery);
var jsonData = [
{ "id": 1, "name": "John", "age": 24, "make": "Chevrolet", "model": "Silverado", "year": 2016 },
{ "id": 2, "name": "Jack", "age": 36, "make": "Toyota", "model": "Corolla", "year": 2018 },
{ "id": 3, "name": "Jill", "age": 29, "make": "Ford", "model": "Escape", "year": 2015 }
];
$('body').append($('<h1>').text('HTML sort'));
$.tableFromJson(jsonData).addClass('stylized sortable').sortable().appendTo('body');
$('body').append($('<h1>').text('Databinding sort'));
$.bindableTable(jsonData, true).addClass('stylized').appendTo('body');
body {
padding: 0.25em !important;
}
h1 {
font-weight: bold !important;
margin-top: 0.75em !important;
margin-bottom: 0.33em !important;
}
table.stylized {
font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
font-size: 12px;
text-align: left;
border-collapse: collapse;
margin: 4px;
width: 600px;
}
table.stylized thead th {
text-transform: capitalize;
font-size: 13px;
color: #039;
background: #b9c9fe;
padding: 6px;
cursor: pointer;
}
table.stylized tbody tr:nth-child(odd) {
background: #f2f5ff;
}
table.stylized tbody tr:nth-child(even) {
background: #e8edff;
}
table.stylized tbody td {
border-top: 1px solid #fff;
color: #669;
padding: 6px;
}
table.stylized tbody tr:hover td {
background: #d0dafd;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>