list.jsを使って難しいことを簡単に。
#はじめに
前に作ったソートのサンプルにページ分割の仕組みを入れます。HTML描画時に全データがTableとして出力されているものを対象とします。ページを動きながらデータを取りに行くようなものではありません。画面内でゴリゴリとやるのでパフォーマンスに難が出るかもしれません。
#やること
普通のHTMLテーブルをlist.jsを使って、ソートしつつページ分割します。
#使ったもの
list.js (version 1.5)
#やってみよう
1.HTMLのテーブルを用意する
前回のサンプルの再掲です。
- ヘッダーのカラムをクリックするとasc/descの切り替えができる
- 切り替えたあとに▲/▼の表示が付く
- 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ページ目へのダイレクトリンクがあります。
<ul>
タグ、<li>
タグでpaginateのパーツが描画されます。自動で出力されるページャーは簡単なHTMLの構造なのでCSSで味付けしときます。CSSはこちらのページを参考にさせていただきました。こちらのCSSを丸っと使うために、<div class="pager">
で囲いました。
<div class="pager">
<ul class="pagination"></ul>
</div>
##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