Sort and filter for table
by Олексій Рачок
HTML
<table>
<thead>
<tr><th>string</th><th>number</th><th>boolean</th></tr>
</thead>
<tbody>
<tr><td>111</td><td>1.1</td><td>false</td></tr>
<tr><td>test4</td><td>1.2</td><td>true</td></tr>
<tr><td>333</td><td>500</td><td>false</td></tr>
<tr><td>test3</td><td>-500</td><td>true</td></tr>
<tr><td>test5</td><td>-500</td><td>false</td></tr>
</tbody>
</table>
<br/>
<table>
<tr>
<th id="facility_header">Facility name</th>
<th>Phone #</th>
<th id="city_header">City</th>
<th>Speciality</th>
</tr>
<tr>
<td>CCC</td>
<td>00001111</td>
<td>Amsterdam</td>
<td>GGG</td>
</tr>
<tr>
<td>JJJ</td>
<td>55544444</td>
<td>London</td>
<td>MMM</td>
</tr>
<tr>
<td>AAA</td>
<td>33332222</td>
<td>Paris</td>
<td>RRR</td>
</tr>
</table>
CSS
table,td,th{border:1px solid black;border-collapse:collapse;padding:2px;}
th{background-color:lightgrey;}
tr:nth-child(1) > th{cursor:n-resize;}
input{height:24px;display:inline-block;padding:0px;margin:0px;text-align:center;padding:0px 4px;}
.filtered{background-color:#FFCCCC;}
JavaScript
$('th').click(function(){
var table = $(this).parents('table').eq(0)
var rows = table.find("tr:not(:has('th'))").toArray().sort(comparer($(this).index()))
this.asc = !this.asc
if (!this.asc){rows = rows.reverse()}
for (var i = 0; i < rows.length; i++){table.append(rows[i])}
})
function comparer(index) {
return function(a, b) {
var valA = getCellValue(a, index), valB = getCellValue(b, index)
return $.isNumeric(valA) && $.isNumeric(valB) ? valA - valB : valA.localeCompare(valB)
}
}
function getCellValue(row, index){ return $(row).children('td').eq(index).html() }
// additional code to apply a filter
$('table').each(function(){
var table = $(this)
var headers = table.find('th').length
var filterrow = $('<tr>').insertAfter($(this).find('th:last()').parent())
for (var i = 0; i < headers; i++){
filterrow.append($('<th>').append($('<input>').attr('type','text').keyup(function(){
table.find('tr').show()
filterrow.find('input[type=text]').each(function(){
var index = $(this).parent().index() + 1
var filter = $(this).val() != ''
$(this).toggleClass('filtered', filter)
if (filter){
var el = 'td:nth-child('+index+')'
var criteria = ":contains('"+$(this).val()+"')"
table.find(el+':not('+criteria+')').parent().hide()
}
})
})))
}
filterrow.append($('<th>').append($('<input>').attr('type','button').val('Clear Filter').click(function(){
$(this).parent().parent().find('input[type=text]').val('').toggleClass('filtered', false)
table.find('tr').show()
})))
})