end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

javascript の onClickイベントによるtable sorter

以下の通りです

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    table  { border-collapse: collapse;}
    th     { position:sticky; top:0;   } /* ヘッダ部の表示位置固定 */
    th, td { border:1px solid #888;    }
    th.sort-asc::after { content:'↓'; }
    th.sort-desc::after{ content:'↑'; }
  </style>
</head>
<body>

<table id="project_progress">
  <thead>
    <tr>
      <th>テーマ</th><th>図面</th><th>COL 1</th><th> COL 2</th><th>COL 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>量産1</td><td>2167</td><td>10759</td><td>33062</td><td>146494</td>
    </tr>
    <tr>
      <td>試作1</td><td>207</td><td>65</td><td>670</td><td>48</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td></td><td>2374</td><td>10824</td><td>33732</td><td>146542</td>
    </tr>
  </tfoot>
</table>

<script>
class TblSorter {
  constructor() {}
  
  init_sort_tbl=(tbl_selector)=>{
        this.tbl_selector = tbl_selector;
        document.querySelectorAll(this.tbl_selector+' thead th').forEach(th=>{
            th.addEventListener('click',()=>{ this.sort_tbl_rows(th) });
        });
        document.querySelector('th').click();
    }
    
    sort_tbl_rows=(th)=> {
        const tbody = document.querySelector(this.tbl_selector+" tbody");
        const records = [];
        for (let row of tbody.rows) {
            const record = {};
            record.row = row;
            if (th.cellIndex >= 2 ){
                record.key = parseInt(row.cells[th.cellIndex].textContent);
            } else {
                record.key = row.cells[th.cellIndex].textContent;
            }
            records.push(record);
        }
        if (th.classList.contains('sort-asc')) {
            records.sort(this.comp_keys_reverse);
            this.purge_sort_marker();
            th.classList.add('sort-desc');
        } else {
            records.sort(this.comp_keys);
            this.purge_sort_marker();
            th.classList.add('sort-asc');
        }
        for (let i = 0; i < records.length; i++) {
            tbody.appendChild(records[i].row);
        }
    }
    
    purge_sort_marker=()=> {
        document.querySelectorAll(this.tbl_selector+' thead th').forEach(th=>{
            th.classList.remove('sort-asc');
            th.classList.remove('sort-desc');
        });
    }
    
    comp_keys=(a, b)=> {
        if (a.key < b.key) return -1;
        if (a.key > b.key) return 1;
        return 0;
    }
    
    comp_keys_reverse=(a, b)=> {
        if (a.key < b.key) return 1;
        if (a.key > b.key) return -1;
        return 0;
    }
}

let tbl_sorter = new TblSorter();
tbl_sorter.init_sort_tbl("#project_progress");
</script>
</body>
</html>