
テーブルを使うなら、ソート機能は欲しいですよね。
でももう実装済だし重いライブラリは使えない。
そんな場合でもテーブルにソート機能を追加することが出来ます。
動作イメージ

スクリプト
function SortTable (tableEl) {
this.tbody = tableEl.getElementsByTagName('tbody');
this.thead = tableEl.getElementsByTagName('thead');
// セルテキストを取得する。
this.getInnerText = function (el) {
if (typeof(el.textContent) != 'undefined') return el.textContent;
if (typeof(el.innerText) != 'undefined') return el.innerText;
if (typeof(el.innerHTML) == 'string') return el.innerHTML.replace(/<[^<>]+>/g,'');
}
// ソートを行う。
this.sort = function (cell) {
const column = cell.cellIndex;
const itm = this.getInnerText(this.tbody[0].rows[1].cells[column]);
let sortfn = this.sortCaseInsensitive;
if (itm.match(/\d\d\d\d+\d\d[-]+\d\d[-]/)) sortfn = this.sortDate; // 年月日フォーマット yyyy-mm-dd
if (itm.replace(/^\s+|\s+$/g,"").match(/^[\d\.]+$/)) sortfn = this.sortNumeric;
this.sortColumnIndex = column;
const newRows = new Array();
for (j = 0; j < this.tbody[0].rows.length; j++) {
newRows[j] = this.tbody[0].rows[j];
}
newRows.sort(sortfn);
if (cell.getAttribute("sortdir") == 'down') {
newRows.reverse();
cell.setAttribute('sortdir','up');
} else {
cell.setAttribute('sortdir','down');
}
for (i=0;i<newRows.length;i++) {
this.tbody[0].appendChild(newRows[i]);
}
}
// 大文字と小文字を区別しないソートを実行する。
this.sortCaseInsensitive = function(a,b) {
aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]).toLowerCase();
bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]).toLowerCase();
if (aa==bb) return 0;
if (aa<bb) return -1;
return 1;
}
// 日付のソートを実行する。
this.sortDate = function(a,b) {
aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]);
bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]);
date1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
date2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
if (date1==date2) return 0;
if (date1<date2) return -1;
return 1;
}
// 数値のソートを実行する。
this.sortNumeric = function(a,b) {
aa = parseFloat(thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]));
if (isNaN(aa)) aa = 0;
bb = parseFloat(thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]));
if (isNaN(bb)) bb = 0;
return aa-bb;
}
const thisObject = this;
const sortSection = this.thead;
// コンストラクタ。
if (!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length > 0)) return;
// コンストラクタ。
if (sortSection && sortSection[0].rows && sortSection[0].rows.length > 0) {
var sortRow = sortSection[0].rows[0];
} else {
return;
}
// コンストラクタ。
for (let i=0; i<sortRow.cells.length; i++) {
sortRow.cells[i].sTable = this;
sortRow.cells[i].onclick = function () {
this.sTable.sort(this);
return false;
}
}
}
実行用サンプルコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テーブルソート</title>
<script type="text/javascript" src="sorttable.js"></script>
<style>
table {
border-spacing: 1;
border-collapse: collapse;
width: 300px;
text-align: left;
font-size: 12px;
font-family: verdana;
background: #c0c0c0;
}
table thead {
cursor: pointer;
}
table thead tr {
background: #c0c0c0;
}
table tbody tr {
background: #f0f0f0;
}
td, th {
border: 1px solid white;
}
</style>
</head>
<body>
<table id="table">
<thead>
<tr>
<th class="c1">氏名</th>
<th class="c2">性別</th>
<th class="c3">年齢</th>
</tr>
</thead>
<tbody>
<tr class="r1">
<td class="c1">鈴木 A太郎</td>
<td class="c2">男</td>
<td class="c3">30</td>
</tr>
<tr class="r2">
<td class="c1">佐藤 B次郎</td>
<td class="c2">男</td>
<td class="c3">32</td>
</tr>
<tr class="r1">
<td class="c1">鈴木 C三郎</td>
<td class="c2">男</td>
<td class="c3">34</td>
</tr>
<tr class="r2">
<td class="c1">鈴木 D子</td>
<td class="c2">女</td>
<td class="c3">31</td>
</tr>
<tr class="r1">
<td class="c1">佐藤 E子</td>
<td class="c2">女</td>
<td class="c3">33</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
const t = new SortTable(document.getElementById('table'), 100);
</script>
</body>
</html>