-
Notifications
You must be signed in to change notification settings - Fork 96
Open
Description
For those who are not using jquery here is the same
(function() {
function tablesort(table, settings) {
const self = this;
this.table = table;
this.thead = this.table.querySelector('thead');
this.settings = Object.assign({}, tablesort.defaults, settings);
this.sortCells = this.thead ? this.thead.querySelectorAll('th:not(.no-sort)') : this.table.querySelectorAll('th:not(.no-sort)');
this.sortCells.forEach(function(cell) {
cell.addEventListener('click', function() {
self.sort(cell);
});
});
this.index = null;
this.direction = null;
}
tablesort.prototype = {
sort: function(th, direction) {
const start = new Date(),
self = this,
rowsContainer = this.table.querySelector('tbody') || this.table,
rows = rowsContainer.querySelectorAll('tr'),
cells = Array.from(rows).map(function(row) {
return row.querySelectorAll('td, th')[th.cellIndex];
}),
sortBy = th.sortBy;
let sortedMap = [];
let unsortedValues = cells.map(function(cell) {
if (sortBy)
return (typeof sortBy === 'function') ? sortBy(th, cell, self) : sortBy;
return (cell.dataset.sortValue != null ? cell.dataset.sortValue : cell.textContent);
});
if (unsortedValues.length === 0) return;
if (this.index !== th.cellIndex) {
this.direction = 'asc';
this.index = th.cellIndex;
} else if (direction !== 'asc' && direction !== 'desc') {
this.direction = (this.direction === 'asc' ? 'desc' : 'asc');
} else {
this.direction = direction;
}
direction = (this.direction === 'asc' ? 1 : -1);
self.table.dispatchEvent(new CustomEvent('tablesort:start', { detail: self }));
self.table.style.display = 'none';
setTimeout(function() {
self.sortCells.forEach(function(cell) {
cell.classList.remove(...self.settings.asc.split(' '), ...self.settings.desc.split(' '));
});
sortedMap = unsortedValues.map(function(value, i) {
return {
index: i,
cell: cells[i],
row: rows[i],
value: value
};
}).sort(function(a, b) {
return self.settings.compare(a.value, b.value) * direction;
});
sortedMap.forEach(function(entry) {
rowsContainer.appendChild(entry.row);
});
th.classList.add(...self.settings[self.direction].split(' '));
self.log('Sort finished in ' + ((new Date()).getTime() - start.getTime()) + 'ms');
self.table.dispatchEvent(new CustomEvent('tablesort:complete', { detail: self }));
self.table.style.display = '';
}, unsortedValues.length > 2000 ? 200 : 10);
},
log: function(msg) {
if ((tablesort.DEBUG || this.settings.debug) && console && console.log) {
console.log('[tablesort] ' + msg);
}
},
destroy: function() {
const self = this;
this.sortCells.forEach(function(cell) {
cell.removeEventListener('click', function() {
self.sort(cell);
});
});
this.table.dtablesort = '';
return null;
}
};
tablesort.DEBUG = false;
tablesort.defaults = {
debug: tablesort.DEBUG,
asc: 'sorted ascending',
desc: 'sorted descending',
compare: function(a, b) {
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
};
HTMLElement.prototype.tablesort = function(settings) {
const previous = this.dtablesort;
if (previous) {
previous.destroy();
}
this.dtablesort = new tablesort(this, settings);
};
})();
//usage
document.querySelectorAll('table').forEach(function(table) {
table.tablesort();
});
document.querySelectorAll('thead th.number').forEach(th=>{
th.sortBy = function(sorter, td) {
return parseInt(td.textContent, 10);
};
});Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels