GPGAgent |
06-14-2020 08:54 AM |
Javascript Sort HTML Table Columns - Asc/Desc Indicators
I have two examples of Javascript that sorts a column of a table, one is
very concise but doesn't show the sort order, the other is very long but
does show the sort order. I thought it would be simple to lift the
arrowhead code and put it into the nice concise bit of code but it
defeats me, maybe someone can point me in the right direction - no pun
intended!
With Arrowheads - using ascii codes 25b2 and 25bc
Code:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>TestSortArrows - html</title>
<script>
function sortTable(Table, col, dir) {
var sortClass, i;
sortTable.sortCol = -1;
sortClass = Table.className.match(/js-sort-\d+/);
if (null != sortClass) {
sortTable.sortCol = sortClass[0].replace(/js-sort-/, '');
Table.className = Table.className.replace(new RegExp(' ?' + sortClass[0] + '\\b'), '');
}
if ('undefined' === typeof col) {
col = sortTable.sortCol;
}
if ('undefined' !== typeof dir) {
sortTable.sortDir = dir == -1 || dir == 'desc' ? -1 : 1;
} else {
sortClass = Table.className.match(/js-sort-(a|de)sc/);
if (null != sortClass && sortTable.sortCol == col) {
sortTable.sortDir = 'js-sort-asc' == sortClass[0] ? -1 : 1;
} else {
sortTable.sortDir = 1;
}
}
Table.className = Table.className.replace(/ ?js-sort-(a|de)sc/g, '');
Table.className += ' js-sort-' + col;
sortTable.sortCol = col;
Table.className += ' js-sort-' + (sortTable.sortDir == -1 ? 'desc' : 'asc');
if (col < Table.tHead.rows[Table.tHead.rows.length - 1].cells.length) {
sortClass = Table.tHead.rows[Table.tHead.rows.length - 1].cells[col].className.match(/js-sort-[-\w]+/);
}
for (i = 0; i < Table.tHead.rows[Table.tHead.rows.length - 1].cells.length; i++) {
if (col == Table.tHead.rows[Table.tHead.rows.length - 1].cells[i].getAttribute('data-js-sort-colNum')) {
sortClass = Table.tHead.rows[Table.tHead.rows.length - 1].cells[i].className.match(/js-sort-[-\w]+/);
}
}
if (null != sortClass) {
sortTable.sortFunc = sortClass[0].replace(/js-sort-/, '');
} else {
sortTable.sortFunc = 'string';
}
Table.querySelectorAll('.js-sort-active').forEach(function(Node) {
Node.className = Node.className.replace(/ ?js-sort-active\b/, '');
});
Table.querySelectorAll('[data-js-sort-colNum="' + col + '"]:not(:empty)').forEach(function(Node) {
Node.className += ' js-sort-active';
});
var rows = [],
TBody = Table.tBodies[0];
for (i = 0; i < TBody.rows.length; i++) {
rows[i] = TBody.rows[i];
}
if ('none' != sortTable.sortFunc) {
rows.sort(sortTable.compareRow);
}
while (TBody.firstChild) {
TBody.removeChild(TBody.firstChild);
}
for (i = 0; i < rows.length; i++) {
TBody.appendChild(rows[i]);
}
}
sortTable.compareRow = function(RowA, RowB) {
var valA, valB;
if ('function' != typeof sortTable[sortTable.sortFunc]) {
sortTable.sortFunc = 'string';
}
valA = sortTable[sortTable.sortFunc](RowA.cells[sortTable.sortCol]);
valB = sortTable[sortTable.sortFunc](RowB.cells[sortTable.sortCol]);
return valA == valB ? 0 : sortTable.sortDir * (valA > valB ? 1 : -1);
};
sortTable.stripTags = function(html) {
return html.replace(/<\/?[a-z][a-z0-9]*\b[^>]*>/gi, '');
};
sortTable.date = function(Cell) {
// If okDate library is available, Use it for advanced Date processing
if (okDate) {
var Date = okDate(sortTable.stripTags(Cell.innerHTML));
return Date ? Date.getTime() : 0;
} else {
return (new Date(sortTable.stripTags(Cell.innerHTML))).getTime() || 0;
}
};
sortTable.number = function(Cell) {
return Number(sortTable.stripTags(Cell.innerHTML).replace(/[^-\d.]/g, ''));
};
sortTable.string = function(Cell) {
return sortTable.stripTags(Cell.innerHTML).toLowerCase();
};
sortTable.raw = function(Cell) {
return Cell.innerHTML;
};
sortTable.last = function(Cell) {
return sortTable.stripTags(Cell.innerHTML).split(' ').pop().toLowerCase();
};
sortTable.input = function(Cell) {
for (var i = 0; i < Cell.children.length; i++) {
if ('object' == typeof Cell.children[i]
&& 'undefined' != typeof Cell.children[i].value
) {
return Cell.children[i].value.toLowerCase();
}
}
return sortTable.string(Cell);
};
sortTable.none = function(Cell) {
return null;
};
sortTable.getClickHandler = function(Table, col) {
return function() {
sortTable(Table, col);
};
};
sortTable.init = function() {
var THead, Tables, Handler;
if (document.querySelectorAll) {
Tables = document.querySelectorAll('table.js-sort-table');
} else {
Tables = document.getElementsByTagName('table');
}
for (var i = 0; i < Tables.length; i++) {
if (!document.querySelectorAll && null === Tables[i].className.match(/\bjs-sort-table\b/)) {
continue;
}
if (Tables[i].attributes['data-js-sort-table']) {
continue;
}
if (!Tables[i].tHead) {
THead = document.createElement('thead');
THead.appendChild(Tables[i].rows[0]);
Tables[i].insertBefore(THead, Tables[i].children[0]);
} else {
THead = Tables[i].tHead;
}
for (var rowNum = 0; rowNum < THead.rows.length; rowNum++) {
for (var cellNum = 0, colNum = 0; cellNum < THead.rows[rowNum].cells.length; cellNum++) {
THead.rows[rowNum].cells[cellNum].setAttribute('data-js-sort-colNum', colNum);
Handler = sortTable.getClickHandler(Tables[i], colNum);
window.addEventListener
? THead.rows[rowNum].cells[cellNum].addEventListener('click', Handler)
: window.attachEvent && THead.rows[rowNum].cells[cellNum].attachEvent('onclick', Handler);
colNum += THead.rows[rowNum].cells[cellNum].colSpan;
}
}
Tables[i].setAttribute('data-js-sort-table', 'true')
}
var element = document.createElement('style');
document.head.insertBefore(element, document.head.childNodes[0]);
var sheet = element.sheet;
//
// Set up and down arrows using ascii codes 25b2 and 25bc
//
sheet.insertRule('table.js-sort-asc thead tr > .js-sort-active:not(.js-sort-none):after {content: "\\25b2";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 0);
sheet.insertRule('table.js-sort-desc thead tr > .js-sort-active:not(.js-sort-none):after {content: "\\25bc";font-size: 0.7em;padding-left: 3px;line-height: 0.7em;}', 0);
};
// Run sortTable.init() when the page loads
window.addEventListener
? window.addEventListener('load', sortTable.init, false)
: window.attachEvent && window.attachEvent('onload', sortTable.init)
;
if (typeof NodeList.prototype.forEach !== "function") {
NodeList.prototype.forEach = Array.prototype.forEach;
}
</script>
</head>
<body>
<H3>Test Sorting table - TestSortArrows.html</h3>
<!--- <table border=1 cellspacing=0> --->
<table class="js-sort-table" border=1 cellspacing=0> <!--- id="demo1" --->
<thead>
<tr>
<th>Asset No</th>
<th>Description</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>JKEL03001234</td><td>Emergency Light</td><td>Rm 35</td>
</tr>
<tr>
<td>JKEL03001239</td><td>Emergency Light</td><td>Rm 36</td>
</tr>
<tr>
<td>JKEP01001234</td><td>Emergency Power Off</td><td>Rm 37</td>
</tr>
<tr>
<td>JKED03001234</td><td>Emergency Door</td><td>Rm 38</td>
</tr>
</tbody>
</table>
</body>
</html>
And the without arrowheads example - I know what to insert. But I don't know how or where exactly.
Code:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>TestNoSortArrows</title>
<script>
function sortTable(table, col, reverse) {
var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
i;
reverse = -((+reverse) || -1);
tr = tr.sort(function (a, b) { // sort rows
return reverse // `-1 *` if want opposite order
* (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
.localeCompare(b.cells[col].textContent.trim())
);
});
for(i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
}
function makeSortable(table) {
var th = table.tHead, i;
th && (th = th.rows[0]) && (th = th.cells);
if (th) i = th.length;
else return; // if no `<thead>` then do nothing
while (--i >= 0) (function (i) {
var dir = 1;
th[i].addEventListener('click', function () {sortTable(table, i, (dir = 1 - dir))});
}(i));
}
function makeAllSortable(parent) {
parent = parent || document.body;
var t = parent.getElementsByTagName('table'), i = t.length;
while (--i >= 0) makeSortable(t[i]);
}
window.onload = function () {makeAllSortable();};
</script>
</head>
<body>
<H3>Test Sorting table - TestNoSortArrows.html</h3>
<!--- <table border=1 cellspacing=0> --->
<table class="js-sort-table" id="demo1" border=1 cellspacing=0>
<thead>
<tr>
<th>Asset No</th>
<th>Description</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>JKEL03001234</td><td>Emergency Light</td><td>Rm 35</td>
</tr>
<tr>
<td>JKEL03001239</td><td>Emergency Light</td><td>Rm 36</td>
</tr>
<tr>
<td>JKEP01001234</td><td>Emergency Power Off</td><td>Rm 37</td>
</tr>
<tr>
<td>JKED03001234</td><td>Emergency Door</td><td>Rm 38</td>
</tr>
</tbody>
</table>
</body>
</html>
Thanks folks
|