LoginSignup
7
7

More than 5 years have passed since last update.

List.jsでHTMLのテーブルをページ分割してソートする

Last updated at Posted at 2018-03-21

list.jsを使って難しいことを簡単に。

はじめに

前に作ったソートのサンプルにページ分割の仕組みを入れます。HTML描画時に全データがTableとして出力されているものを対象とします。ページを動きながらデータを取りに行くようなものではありません。画面内でゴリゴリとやるのでパフォーマンスに難が出るかもしれません。

やること

普通のHTMLテーブルをlist.jsを使って、ソートしつつページ分割します。

使ったもの

list.js (version 1.5)

やってみよう

1.HTMLのテーブルを用意する

前回のサンプルの再掲です。
- ヘッダーのカラムをクリックするとasc/descの切り替えができる
- 切り替えたあとに▲/▼の表示が付く
- HTMLテーブルの内容によらず、初期表示は名前の昇順 生まれ年の逆順

zenkai.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( 'name', {order : 'asc' });
</script>

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

このままだとテーブルのデータが少なくページ移動する実感がなくなるので、いい感じで増やしてください。以降のサンプルは30個に増やしたときの例です。

2. page分割(paginate)の設定する

list.jsの初期化の部分を修正します。

  var options = {
    valueNames: [ 'name', 'born' ],
    page: 2,
    pagination: {
        paginationClass:'pagination',
        innerWindow:1,
        outerWindow:1,
    }
  };
  var userList = new List('users', options);

page

1ページあたりの行数を指定できます。指定しない場合は200になるそうです。

pagination

ページャーのパーツの動きを設定します。マニュアルを見ると以下のプロパティが指定できます(一部意訳)
paginationClass
ページを動かすためのHTMLのパーツの埋め込むためのclass名を指定する。何も指定しないときは、"pagination"

innerWindow
今のページの前後に何ページ移動可能にするかを数値で指定する。何も指定しないときは "2"。5ページ目にいるときは、前向きに3,4 後ろ向きに6,7が移動できるようになる。

outerWindow
今いるところとは関係なしに両端を何ページ出すかを指定する。何も指定しないときは "0"の扱い。全部で何ページあるかを表現できるので1は指定しておきたいところ。

left
outerWindowと同じだが、左端(1ページ目)から何個ジャンプできるようにするかを指定する。

right
leftと同じ。右端(最終ページ)から何ページを直接移動できるようにするか指定できる。

今回の設定だと、1ページ2行表示、隣のページには1ページまで移動できる、両端のページも1ページ移動でいる状態となります。leftとrightは使っていませんが、左右非対称にしたいときは使ってみてください。outerWindowで足りそうですけど。

3.ページャーを埋め込む

このままだとページ移動のパーツは表示されません。list.jsにはページ移動のパーツを埋め込む仕組みがあるので活用します。といっても、以下のHTMLを入れるだけです。

<ul class="pagination"></ul>

ブラウザで再読み込みすると、こんな感じのパーツが出てきます。4ページ目まで移動したところです。前後に1ページ分のリンク、今いる場所に関係なく、1ページ目と15ページ目へのダイレクトリンクがあります。

image.png

<ul>タグ、<li>タグでpaginateのパーツが描画されます。自動で出力されるページャーは簡単なHTMLの構造なのでCSSで味付けしときます。CSSはこちらのページを参考にさせていただきました。こちらのCSSを丸っと使うために、<div class="pager">で囲いました。

    <div class="pager">
        <ul class="pagination"></ul>
    </div>

image.png

4.ソートした時の挙動を変える

この状態でほぼ完成かと思ったのですが、ページ移動後にカラムヘッダーを使ってソートすると、データの並び替えは行われますがページ番号がそのまま(サンプルだと4のまま)なので、不思議な挙動をします。ソートしたときはページ番号が1にリセットされるのが期待する動きかなと思うので、その部分を追加しておきます。不要であれば撤去してください。

  userList.on('sortStart', function(list){
      console.log(list.i);
      list.i=1;
    }
  );

userListオブジェクトにイベント発生時のコールバックを仕込みました。ソートが始まるときに呼ばれる関数内でlistの番号を1にします。list.jsのイベントはこちらのページで解説してあります。

完成品です

<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">1.Jonny Stromberg</td>
          <td class="born">1986</td>
        </tr>
        <tr>
          <td class="name">2.Jonas Arnklint</td>
          <td class="born">1985</td>
        </tr>
        <tr>
          <td class="name">3.Martina Elm</td>
          <td class="born">1986</td>
        </tr>
        <tr>
          <td class="name">4.Gustaf Lindqvist</td>
          <td class="born">1983</td>
        </tr>

<!--省略-->

          <tr>
            <td class="name">29.Martina Elm</td>
            <td class="born">1986</td>
          </tr>
          <tr>
            <td class="name">30.Gustaf Lindqvist</td>
            <td class="born">1983</td>
          </tr>

    </tbody>
    </table>

    <!-- wrap list.js pagination by div.pager for using pager sample css -->
    <div class="pager">
        <ul class="pagination"></ul>
    </div>

  </div>

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

  userList.on('sortStart', function(a){
      console.log(a.i);
      a.i=1;
    }
  );

  //for initial sort
  userList.sort( 'name', {order : 'asc' });
  </script>

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

<style>
/* style for pager and pagination from http://wwx.jp/css-pagination*/

.pager {
    overflow: hidden;
}

.pager ul {
    list-style: none;
    position: relative;
    left: 50%;
    float: left;
}

.pager ul li {
    margin: 0 1px;
    position: relative;
    left: -50%;
    float: left;
}

.pager ul li span,
.pager ul li a {
    display: block;
    font-size: 16px;
    padding: 0.6em 1em;
    border-radius: 3px;
}

.pager ul li a {
    background: #EEE;
    color: #000;
    text-decoration: none;
}

.pager ul li a:hover {
    background: #333;
    color: #FFF;
}

/* added by myself */
.pager ul li.active{
    font-weight: bold;
}
</style>

コードをそのままHTMLファイルとして保存すれば動きます。

まとめ

今回のpaginationはCSSを直接書きましたが、bootstarpのpaginationと仕組みは同じような感じなので、そのまま使えるのではないかと思います。ページャー、ページネイト、ニホンゴムズカシイネ

参考にしたページ

http://listjs.com/docs/pagination/
http://wwx.jp/css-pagination

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7