JavaScript
list.js

List.jsでHTMLのテーブルをソートする

困ったこと

List.jsを使って簡単にテーブルのヘッダーをクリックしてソートするサンプルがない

やること

List.jsを使ってHTMLのテーブルのカラム部分を触るだけで並び替えられるようにする

使ったもの

list.js (version 1.5)

やってみよう

1.テーブル形式のデータを作る

いつの通り、本家のサンプルを拝借
http://listjs.com/examples/table/

一番外側要素<div id="users">のIDの値と、JSの第一引数new List('users', options);が一致していないとListJSのインスタンスが作れないので注意。

<div id="users">
  <input class="search" placeholder="Search" />
  <button class="sort" data-sort="name">
    Sort by name
  </button>
  <table>
    <!-- IMPORTANT, class="list" have to be at tbody -->
    <tbody class="list">
      <tr>
        <td class="name">Jonny Stromberg</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Jonas Arnklint</td>
        <td class="born">1985</td>
      </tr>
      <tr>
        <td class="name">Martina Elm</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Gustaf Lindqvist</td>
        <td class="born">1983</td>
      </tr>
    </tbody>
  </table>

</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<script>
var options = {
  valueNames: [ 'name', 'born' ]
};
var userList = new List('users', options);
</script>

2.テーブルにヘッダーつけよう

検索用のテキストボックスとソートのボタンを削除して、テーブルのヘッダーを付ける。これじゃ、まだソートはできない。<div id="users">ではなく<table id="users">でも同じ動きになる。

<div id="users">
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Born</th>
       </tr>
    </thead>
    <!-- IMPORTANT, class="list" have to be at tbody -->
    <tbody class="list">
      <tr>
        <td class="name">Jonny Stromberg</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Jonas Arnklint</td>
        <td class="born">1985</td>
      </tr>
      <tr>
        <td class="name">Martina Elm</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Gustaf Lindqvist</td>
        <td class="born">1983</td>
      </tr>
    </tbody>
  </table>

</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<script>
var options = {
  valueNames: [ 'name', 'born' ]
};
var userList = new List('users', options);
</script>

3.カラムクリックでソート

ソートのきっかけとなるオブジェクトにclass="sort"を付けるとソートのスイッチになる。で、そのスイッチを押したときに何をソートさせるのかを関係づけるのかは、data-sort="xxx"で指定できる。

<div id="users">
  <table>
    <thead>
      <tr>
        <th class="sort" data-sort="name">Name</th> <!-- ここ変更点-->
        <th class="sort" data-sort="born">Born</th> <!-- ここ変更点-->
      </tr>
    </thead>
    <!-- IMPORTANT, class="list" have to be at tbody -->
    <tbody class="list">
      <tr>
        <td class="name">Jonny Stromberg</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Jonas Arnklint</td>
        <td class="born">1985</td>
      </tr>
      <tr>
        <td class="name">Martina Elm</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Gustaf Lindqvist</td>
        <td class="born">1983</td>
      </tr>
    </tbody>
  </table>

</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<script>
var options = {
  valueNames: [ 'name', 'born' ]
};
var userList = new List('users', options);
</script>

これで、ヘッダーを触るとソートできるようになる。Nameヘッダーカラムを触ると、data-sort="name"なので、nameカラムの値で並び替えができるようになるというわけ。

4.どこでソートしてるのか分かるようにする

list.jsでソートすると、sortクラスを持つオブジェクトにascかdescのクラスを追加してくれる。なので、sort.ascとsort.descのスタイルを用意して待ち伏せしておくだけで、画面が勝手に変化する。
たとえば、以下のコードを追加すると

<style>
.sort.desc:after {
  content:"▼";
}
.sort.asc:after {
  content:"▲";
}
</style>

Nameでascしたとき
list.js.asc.png

Bornでdescしたとき
list.js.desc.png

こんな画面表示ができるようになる。

5.初期表示を変える

HTMLのテーブルの自体を変えずに初期表示時の並び順を変える。これはLoad時にスクリプトが動くようにするだけでよいので簡単。生まれ年の大きい順に並べます。

var options = {
  valueNames: [ 'name', 'born' ]
};
var userList = new List('users', options);
userList.sort( 'born', {order : 'desc'} );

sort functionのマニュアルはこちらを参照
http://listjs.com/api/#sort

最終形

今日の最終形はこちらです。

<div id="users">
  <table>
    <thead>
      <tr>
        <th class="sort" data-sort="name">Name</th>
        <th class="sort" data-sort="born">Born</th>
      </tr>
    </thead>
    <!-- IMPORTANT, class="list" have to be at tbody -->
    <tbody class="list">
      <tr>
        <td class="name">Jonny Stromberg</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Jonas Arnklint</td>
        <td class="born">1985</td>
      </tr>
      <tr>
        <td class="name">Martina Elm</td>
        <td class="born">1986</td>
      </tr>
      <tr>
        <td class="name">Gustaf Lindqvist</td>
        <td class="born">1983</td>
      </tr>
    </tbody>
  </table>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<script>
var options = {
  valueNames: [ 'name', 'born' ]
};
var userList = new List('users', options);
userList.sort( 'born', {order : 'desc' });
</script>

<style>
.sort.desc:after {
  content:"▼";
}
.sort.asc:after {
  content:"▲";
}
</style>

追記

2018/12/9

先頭の<div id="users">