Sortable.js
Sorteerbare tabellen (broncode)
/**
* Make any HTML table sortable by clicking column headers.
*
* @param {string|HTMLTableElement} table - table element or its ID
* @param {Object} [opts]
* @param {string} [opts.ascClass] - CSS class added to ascending header (default "sort-asc")
* @param {string} [opts.descClass] - CSS class added to descending header (default "sort-desc")
* @example
* <script src="/js/sortable.js"></script>
* <script>new BonarooSortable("my-table");</script>
*/
function BonarooSortable(table, opts) {
if (typeof table === "string") {
table = document.getElementById(table);
}
if (!table || table.tagName !== "TABLE") {
throw new Error("BonarooSortable: element is not a <table>");
}
this.table = table;
this.ascClass = (opts && opts.ascClass) || "sort-asc";
this.descClass = (opts && opts.descClass) || "sort-desc";
this.currentCol = -1;
this.ascending = true;
var headers = table.querySelectorAll("thead th");
for (var i = 0; i < headers.length; i++) {
headers[i].style.cursor = "pointer";
headers[i].setAttribute("data-sort-col", i);
headers[i].addEventListener("click", this._onHeaderClick.bind(this, i));
}
}
BonarooSortable.prototype._onHeaderClick = function _onHeaderClick(colIndex) {
if (this.currentCol === colIndex) {
this.ascending = !this.ascending;
} else {
this.currentCol = colIndex;
this.ascending = true;
}
this._sort(colIndex, this.ascending);
this._updateClasses(colIndex, this.ascending);
};
BonarooSortable.prototype._sort = function _sort(colIndex, asc) {
var tbody = this.table.querySelector("tbody") || this.table;
var rows = Array.prototype.slice.call(tbody.querySelectorAll("tr"));
rows.sort(function (a, b) {
var cellA = (a.children[colIndex] || {}).textContent || "";
var cellB = (b.children[colIndex] || {}).textContent || "";
var numA = parseFloat(cellA.replace(/[^\d.\-]/g, ""));
var numB = parseFloat(cellB.replace(/[^\d.\-]/g, ""));
var result;
if (!isNaN(numA) && !isNaN(numB)) {
result = numA - numB;
} else {
result = cellA.localeCompare(cellB, undefined, { sensitivity: "base" });
}
return asc ? result : -result;
});
for (var i = 0; i < rows.length; i++) {
tbody.appendChild(rows[i]);
}
};
BonarooSortable.prototype._updateClasses = function _updateClasses(colIndex, asc) {
var headers = this.table.querySelectorAll("thead th");
for (var i = 0; i < headers.length; i++) {
headers[i].classList.remove(this.ascClass, this.descClass);
}
if (headers[colIndex]) {
headers[colIndex].classList.add(asc ? this.ascClass : this.descClass);
}
};
/**
* Write the table before the current executing script element.
* Handy for inline usage, similar to BonarooTimer.
*/
BonarooSortable.prototype.write = function write(id) {
if (!this.table.id && id) {
this.table.id = id;
}
if (document.currentScript) {
document.currentScript.insertAdjacentElement("beforebegin", this.table);
}
};