july 28, 2021
Sorting table rows can't be performed with CSS, only javascript can do that.
To generate new table content, try reloading / refreshing this page with your browser. And if you need to see different number of rows, enter number of rows here first: then click following button: .
alphanumeric | numeric |
---|
<div id="demo"> <table> <thead><tr> <th class="sort-able alph">alphanumeric</th> <th class="sort-able num">numeric</th> </tr></thead> <tbody></tbody> </table> </div><!--#demo ends-->
.sort-able{ position: relative; padding-right: 1em !important;/*give space for sort icon*/ } .sort-able:after{ content: ''; position: absolute; bottom: 0; right: 0; padding: 0.5em; background-repeat: no-repeat; background-image: url(sort-able.svg);/*sort icon file, an svg sprite containing 2 icons*/ background-position: 0 0; } .sort-able.asc:after{/*ascending sort icon*/ background-position: 100% 0; } .sort-able.desc:after{/*descending sort icon = rotated, ascending icon*/ background-position: 100% 0; transform: rotate(180deg); }
'use strict'; +function(){ //column index of th to parent element let iColCompare = -1; //listen to click on ths document.getElementById('demo').addEventListener('click', function(ev){ const trs = this.getElementsByTagName('tbody')[0].getElementsByTagName('tr'), rows = [], clicked = ev.target;//clicked element let isAlph = true, isAsc = true; //define function to populate rows from trs function trsToRows(){ rows.length = 0;//delete rows for(let i = 0; i < trs.length; i++){ const tds = trs[i].getElementsByTagName('td'), cols = []; for(let j = 0; j < tds.length; j++) cols.push(tds[j].textContent); rows.push(cols); } } //define function to populate trs from rows function rowsToTrs(){ for(let i = 0; i < trs.length; i++){ const tds = trs[i].getElementsByTagName('td'); for(let j = 0; j < tds.length; j++) tds[j].textContent = rows[i][j]; } } //define sorting function function compare(s1, s2){ if(isAlph){ const minSLen = Math.min(s1[iColCompare].length, s2[iColCompare].length); //get minimum of 2 string lengths let delt = 0; for(let i = 0; i < minSLen; i++){ if(isAsc) delt += s1[iColCompare].charCodeAt(i) - s2[iColCompare].charCodeAt(i); else delt += s2[iColCompare].charCodeAt(i) - s1[iColCompare].charCodeAt(i); if(delt !== 0) break; } return delt; } else{ if(isAsc) return Number(s1[iColCompare]) - Number(s2[iColCompare]); else return Number(s2[iColCompare]) - Number(s1[iColCompare]); } } //if clicked element has sortable class and iColCompare isn't currently used if(clicked.className.search(/\bsort-able\b/) !== -1 && iColCompare === -1){ //trs -> rows trsToRows(); //define iColCompare 1st let el = clicked; for(iColCompare = 0; (el = el.previousElementSibling); iColCompare++); //walk through ths const ths = clicked.parentNode.getElementsByClassName('sort-able'); for(let i = 0; i < ths.length; i++) if(ths[i] !== clicked)//if a th isn't the clicked element, remove asc / desc classes ths[i].className = ths[i].className.replace(/\bdesc\b|\basc\b/g, ''); else{//if a th is the clicked element perform sorting on rows if(ths[i].className.search(/\basc\b/) !== -1){ ths[i].className = ths[i].className.replace(/\basc\b/g, 'desc'); isAlph = (ths[i].className.search(/\balph\b/) !== -1);//define alphabetic or numerical sorting isAsc = false;//define descending sort rows.sort(compare); } else{ if(ths[i].className.search(/\bdesc\b/) !== -1) ths[i].className = ths[i].className.replace(/\bdesc\b/g, 'asc'); else ths[i].className = ths[i].className.trim() + ' asc'; isAlph = (ths[i].className.search(/\balph\b/) !== -1);//define alphabetic or numerical sorting isAsc = true;//define ascending sort rows.sort(compare); } iColCompare = -1;//sorting done: reset iColCompare rowsToTrs();//rows -> trs } } }); }();
Comments