Filter/sort table demo
Filter/sort table
by mrjordy
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.2.2/tinysort.min.js"></script>
<ul class="tabs" role="toolbar" aria-label="backpack sorting options" aria-controls="backpackGrid">
<li class="selected"> <a class="viewAll" aria-selected="true" data-filter="" href="javascript: void(0);">View All</a>
</li>
<li> <a aria-selected="false" data-filter="group1" href="javascript: void(0);">group 1</a>
</li>
<li> <a aria-selected="false" data-filter="group2" href="javascript: void(0);">group 2</a>
</li>
<li> <a aria-selected="false" data-filter="group3" href="javascript: void(0);">group 3</a>
</li>
</ul>
<table id="backpackGrid" summary="Filterable & sortable backpack selection table">
<caption id="backpackCaption" role="status" aria-live="polite">Filterable & sortable backpack selection table (this needs to be offscreen - avoid display:none)</caption>
<thead>
<tr>
<th role="columnheader" aria-sort="none" scope="col"><a>product</a>
</th>
<th role="columnheader" aria-sort="none" scope="col"><a>price</a>
</th>
<th role="columnheader" aria-sort="none" scope="col"><a>capacity</a>
</th>
<th role="columnheader" aria-sort="none" scope="col"><a>monogrammable</a>
</th>
</tr>
</thead>
<tbody>
<tr class="group1" scope="row">
<td role="rowheader">Junior Original</td>
<td>$39</td>
<td>6 liters</td>
<td class="monogram-false">not monogrammable</td>
</tr>
<tr class="group2" scope="row">
<td role="rowheader">Bean's Pal Packs</td>
<td>$45</td>
<td>9 liters</td>
<td class="monogram-true">monogrammable</td>
</tr>
<tr class="group1 group3" scope="row">
<td...
CSS
td.monogram-true, td.monogram-false {
text-indent: -9999px;
}
td, th {
border: 1px solid #e9e9e9;
padding: 10px;
background: #fff;
}
td.monogram-true {
background: url('http://vignette3.wikia.nocookie.net/roblox/images/5/57/Very-Basic-Checkmark-icon.png') center center no-repeat;
background-size: contain;
width: 10px;
height: 10px;
}
.hidden {
display: none;
}
#backpackGrid th {
background: #d9d9d9 url('http://www.ssa.gov/accessibility/bpl/bps/tables/basic/example/css/img/bg.gif') no-repeat right;
text-align: left;
min-width: 130px;
}
#backpackGrid th.asc {
background-image: url('http://www.ssa.gov/accessibility/bpl/bps/tables/basic/example/css/img/asc.gif');
}
#backpackGrid th.desc {
background-image: url('http://www.ssa.gov/accessibility/bpl/bps/tables/basic/example/css/img/desc.gif');
}
.tabs {
padding-bottom: 20px;
}
.tabs li {
display: inline;
padding: 10px;
border: 1px solid #e9e9e9;
margin: 5px;
}
.tabs li.selected {
background: gold;
}
JavaScript
//sort table w/ tinysort - pulled from: http://tinysort.sjeiti.com/#sorting-tables
var table = document.getElementById('backpackGrid'),
tableHead = table.querySelector('thead'),
tableHeaders = tableHead.querySelectorAll('th'),
tableBody = table.querySelector('tbody');
tableHead.addEventListener('click', function (e) {
var tableHeader = e.target,
textContent = tableHeader.textContent,
tableHeaderIndex, isAscending, order;
while (tableHeader.nodeName !== 'TH') {
tableHeader = tableHeader.parentNode;
}
tableHeaderIndex = Array.prototype.indexOf.call(tableHeaders, tableHeader);
isAscending = tableHeader.getAttribute('data-order') === 'asc';
order = isAscending ? 'desc' : 'asc';
//reset other columns
$('#backpackGrid').find('th').removeClass('asc desc').attr('data-order','none').attr('aria-sort','none');
//set order on clicked header
tableHeader.setAttribute('data-order', order);
/* accessibility */
//set aria sort attr
tableHeader.setAttribute('aria-sort', order);
tableHeader.setAttribute("class", order);
// build aria-live message
var sortOrder;
if (isAscending) {
sortOrder = "Ascending order";
} else {
sortOrder = "Descending order";
}
$('#backpackCaption').empty().append("Backpacks sorted by " + textContent + ": " + sortOrder);
/* end accessibility */
// call tinysort
tinysort(
tableBody.querySelectorAll('tr'), {
selector: 'td:nth-child(' + (tableHeaderIndex + 1) + ')',
order: order
});
});
// filter table & update accessible table caption
$('.tabs li a').on('click', function(){
var $this = $(this),
$group = $this.attr('data-filter');
if(!$this.hasClass('viewAll')){
$('#backpackGrid').find('.' + $group).addClass('hidden');
$('#backpackGrid').find('tr').not('.' + $group).removeClass('hidden');
//update table caption
...