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

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

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

#使ったもの
list.js (version 1.5)

jsfiddleに動く成果物を置いておきました
https://jsfiddle.net/kanaxx/78odztmv/

#やってみよう
## 1.テーブル形式のデータを作る
いつの通り、本家のサンプルを拝借
http://listjs.com/examples/table/

サンプルはこちらに移動したもよう(2019/9/5)
https://codepen.io/javve/pen/pJMJKx


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

```html
<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">`でも同じ動きになる。

```html
<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"`で指定できる。

```html
<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"`なので、`class="name"`のタグの中の値で並び替えができるようになるというわけ。

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

```html
<style>
.sort.desc:after {
  content:"▼";
}
.sort.asc:after {
  content:"▲";
}
</style>
```
Nameでascしたとき
![list.js.asc.png](https://qiita-image-store.s3.amazonaws.com/0/168315/15075be1-6285-9744-1da4-8e3f061f10bd.png)

Bornでdescしたとき
![list.js.desc.png](https://qiita-image-store.s3.amazonaws.com/0/168315/b4974633-baf3-b559-767a-de37a38bfaf1.png)

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

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

```js

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

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

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

```html
<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">```は<div>の間```<table id="users">```でも大丈夫です。


#次回のチャレンジ
- [カンマ区切りの数値や小数点が入ったときのカラムをキレイにソートしたい。](https://qiita.com/kanaxx/items/513640b066d93b49edac)
- [sort用のfunctionを定義できるようなので、function使ってみる](https://qiita.com/kanaxx/items/402d002dbc6228902dcd)
- [sortとページ分割を同時にやる](https://qiita.com/kanaxx/items/6e04a0971256c839ba5a)