tippy.js
Version:
Vanilla JS Tooltip Library
169 lines (156 loc) • 4.41 kB
JavaScript
var addSorting = (function() {
'use strict'
var cols,
currentSort = {
index: 0,
desc: false
}
// returns the summary table element
function getTable() {
return document.querySelector('.coverage-summary')
}
// returns the thead element of the summary table
function getTableHeader() {
return getTable().querySelector('thead tr')
}
// returns the tbody element of the summary table
function getTableBody() {
return getTable().querySelector('tbody')
}
// returns the th element for nth column
function getNthColumn(n) {
return getTableHeader().querySelectorAll('th')[n]
}
// loads all columns
function loadColumns() {
var colNodes = getTableHeader().querySelectorAll('th'),
colNode,
cols = [],
col,
i
for (i = 0; i < colNodes.length; i += 1) {
colNode = colNodes[i]
col = {
key: colNode.getAttribute('data-col'),
sortable: !colNode.getAttribute('data-nosort'),
type: colNode.getAttribute('data-type') || 'string'
}
cols.push(col)
if (col.sortable) {
col.defaultDescSort = col.type === 'number'
colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>'
}
}
return cols
}
// attaches a data attribute to every tr element with an object
// of data values keyed by column name
function loadRowData(tableRow) {
var tableCols = tableRow.querySelectorAll('td'),
colNode,
col,
data = {},
i,
val
for (i = 0; i < tableCols.length; i += 1) {
colNode = tableCols[i]
col = cols[i]
val = colNode.getAttribute('data-value')
if (col.type === 'number') {
val = Number(val)
}
data[col.key] = val
}
return data
}
// loads all row data
function loadData() {
var rows = getTableBody().querySelectorAll('tr'),
i
for (i = 0; i < rows.length; i += 1) {
rows[i].data = loadRowData(rows[i])
}
}
// sorts the table using the data for the ith column
function sortByIndex(index, desc) {
var key = cols[index].key,
sorter = function(a, b) {
a = a.data[key]
b = b.data[key]
return a < b ? -1 : a > b ? 1 : 0
},
finalSorter = sorter,
tableBody = document.querySelector('.coverage-summary tbody'),
rowNodes = tableBody.querySelectorAll('tr'),
rows = [],
i
if (desc) {
finalSorter = function(a, b) {
return -1 * sorter(a, b)
}
}
for (i = 0; i < rowNodes.length; i += 1) {
rows.push(rowNodes[i])
tableBody.removeChild(rowNodes[i])
}
rows.sort(finalSorter)
for (i = 0; i < rows.length; i += 1) {
tableBody.appendChild(rows[i])
}
}
// removes sort indicators for current column being sorted
function removeSortIndicators() {
var col = getNthColumn(currentSort.index),
cls = col.className
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '')
col.className = cls
}
// adds sort indicators for current column being sorted
function addSortIndicators() {
getNthColumn(currentSort.index).className += currentSort.desc
? ' sorted-desc'
: ' sorted'
}
// adds event listeners for all sorter widgets
function enableUI() {
var i,
el,
ithSorter = function ithSorter(i) {
var col = cols[i]
return function() {
var desc = col.defaultDescSort
if (currentSort.index === i) {
desc = !currentSort.desc
}
sortByIndex(i, desc)
removeSortIndicators()
currentSort.index = i
currentSort.desc = desc
addSortIndicators()
}
}
for (i = 0; i < cols.length; i += 1) {
if (cols[i].sortable) {
// add the click event handler on the th so users
// dont have to click on those tiny arrows
el = getNthColumn(i).querySelector('.sorter').parentElement
if (el.addEventListener) {
el.addEventListener('click', ithSorter(i))
} else {
el.attachEvent('onclick', ithSorter(i))
}
}
}
}
// adds sorting functionality to the UI
return function() {
if (!getTable()) {
return
}
cols = loadColumns()
loadData(cols)
addSortIndicators()
enableUI()
}
})()
window.addEventListener('load', addSorting)