JavaScript で表の並べ替え

表 (table) の表見出し (th) をクリックして表本体 (tbody) の行を並び替えできるようにするためのコードです。

HTML

<table id="sortable-table">
    <thead>
        <tr>
            <th>Head 1</th>
            <th>Head 2</th>
            <th>Head 3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>ABC</td>
            <td>123</td>
            <td>ZYX</td>
        </tr>
        <tr>
            <td>DEF</td>
            <td>456</td>
            <td>WVU</td>
        </tr>
        <tr>
            <td>GHI</td>
            <td>789</td>
            <td>TSR</td>
        </tr>
    </tbody>
</table>

<script>
    import SortableTable from 'sortable-table.js';
    const table = document.getElementById('sortable-table');
    new SortableTable(table);
</script>

JavaScript

JavaScript のモジュールファイル (sortable-table.js) は次のとおりです。

export default class SortableTable {
    constructor(element) {
        const tbody = element.getElementsByTagName('tbody')[0];
        element.querySelectorAll('th').forEach((th) => {
            th.style.cursor = 'n-resize';
            th.onclick = (event) => {
                const values = [];
                for (let i = 1; i < element.rows.length; i++) values.push({ row: element.rows[i], value: element.rows[i].cells[event.target.cellIndex].textContent });

                if (event.target.style.cursor === 'n-resize') {
                    values.sort((a, b) => {
                        if (a.value > b.value) return 1;
                        if (a.value < b.value) return -1;
                        return 0;
                    });
                    event.target.style.cursor = 's-resize';

                 } else {
                    values.sort((a, b) => {
                        if (a.value > b.value) return -1;
                        if (a.value < b.value) return 1;
                        return 0;
                    });
                    event.target.style.cursor = 'n-resize';
                }

                for (const value of values) tbody.appendChild(value.row);
            };
        });
    }
}