デモ
画面下部にあるページネーションの「 …
」 のリンクをクリックしたら、入力画面が表示されます。
そこに半角数字で値を入れたら、指定したページ番号に一致するレコードを表示します。
何がしたいか
jquery.dataTable.jsでページネーションを使用すると、画像みたいなページネーションが自動で生成されます。
ページ遷移も挟まずテーブルのレコード表示を切り替えてくれて大変便利ですね。
ですが、ひとつだけ不満があり。
「 …
」の部分、クリックしても何も起きません。
なんだかもったいない気がします。これが膨大なレコード数になった時、
例えば569ページ目の情報にジャンプする場合にチマチマ後ろのほうのページ番号をクリックしまくるのは嫌だなって思いました。
知る人ぞ知る e*hen*a*.org
というサイトに同様のページジャンプ機能があり、
これが便利だと感じたので、自分でも作ってみようと思いました。
あとついでに、半角数字しか入力できないように制限しています。
準備
HTMLを準備します。十分な量のtd要素がないと「 …
」は表示されないので、いっぱい tr>td
要素を用意してください。100個ぐらい。
<html>
<head>
<title>test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/plug-ins/f2c75b7247b/integration/bootstrap/3/dataTables.bootstrap.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/1.0.4/css/dataTables.responsive.css" />
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.5/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/plug-ins/f2c75b7247b/integration/bootstrap/3/dataTables.bootstrap.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/responsive/1.0.4/js/dataTables.responsive.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12">
<table id="example" class="table table-bordered table-hover">
<thead>
<tr>
<th>aaa</th>
<th>bbb</th>
<th>ccc</th>
<th>ddd</th>
<th>eee</th>
</tr>
</thead>
<tbody>
<?php for($i = 0; $i < 100; $i++): ?>
<tr>
<td><?php echo $i; ?></td>
<td><?php echo $i; ?></td>
<td><?php echo $i; ?></td>
<td><?php echo $i; ?></td>
<td><?php echo $i; ?></td>
</tr>
<?php endfor; ?>
</tbody>
</table>
</div>
</div>
</body>
</html>
実装
jQueryとjquery.datatable.jsを事前に読み込んでいる必要があります。当たり前ですが
/**
* datatable pagination jump
*
* @link http://drmsite.blogspot.com/2015/03/datatable-jump-to-page-functionality.html
* @link https://datatables.net/forums/discussion/32860/how-i-get-id-table
* @link https://datatables.net/reference/api/draw()
*/
function dataTablePaginationJump(dtElem)
{
var dtElem = dtElem !== undefined ? dtElem : "table.dataTable";
var myTable = $(dtElem).DataTable();
var myTableId = myTable.table().node().id; // e.g. "DataTables_Table_0"
var myTableEllipsisId = myTableId + "_ellipsis";
$(document).on('click', "#" + myTableEllipsisId, function(){
var pageInfo = myTable.page.info();
var firstPageNum = 1;
var lastPageNum = pageInfo.pages;
var num = promptForNumberRange(firstPageNum, lastPageNum);
if(num){
num = parseInt(num, 10);
var index = num - 1;
myTable.page(index).draw(false);
}
});
}
/**
* Show prompt that are valid only for numeric.
*
* @param int minNum
* @param int maxNum
* @param str placeholder (optional)
* @return int or bool(false)
*/
function promptForNumberRange(minNum, maxNum, placeholder)
{
var minNum = parseInt(minNum, 10);
var maxNum = parseInt(maxNum, 10);
if(placeholder === undefined){
var placeholder = "確認したいページ番号を半角数字で入力してください。\n有効な値は次の範囲です。 " + minNum + " ~ " + maxNum;
}
var inputVal = window.prompt(placeholder, "");
if(inputVal === null){ // cancel button pressed.
return false;
}
var inputNum = parseInt(inputVal, 10);
return checkNumberRange(minNum, maxNum, inputNum);
}
/**
* Check if input value is within the specified numerical range.
*
* @param int minNum
* @param int maxNum
* @param int inputNum
* @return int
* @link https://stackoverflow.com/questions/15047140/javascript-prompt-number-and-continue-prompting-if-answer-is-wrong
*/
function checkNumberRange(minNum, maxNum, inputNum)
{
var minNum = parseInt(minNum, 10);
var maxNum = parseInt(maxNum, 10);
var inputNum = parseInt(inputNum, 10);
if(inputNum >= minNum && inputNum <= maxNum){
return inputNum;
}
else if(isNaN(inputNum)){
var errorText = "入力された値が半角数値ではありません。\n有効な値は次の範囲です。 " + minNum + " ~ " + maxNum;
return promptForNumberRange(minNum, maxNum, errorText);
}
else {
var errorText = "入力された値(" + inputNum + ") は有効な値ではありません。\n有効な値は次の範囲です。 " + minNum + " ~ " + maxNum;
return promptForNumberRange(minNum, maxNum, errorText);
}
}
実行
$(function(){
$('table#example').DataTable();
dataTablePaginationJump('table#example');
});
デモではセレクタをid指定していますが、クラス指定でも動作します。
その場合、tableには「DataTables_Table_0」みたいなid属性が自動で付与されます。(jquery.datatable.jsによって自動で付与される)
あと、tableタグに「dataTable」というクラスを付与していれば、関数に引数を入力不要にしています。
$(function(){
$('table.dataTable').DataTable();
dataTablePaginationJump();
});
余談
どうでもいいですけど、サンプル用のtdタグはEmmetを使って次のコードから生成しました
tr*1000>th{$}*5
デフォルトは1ページ毎に10行表示なので、100ページ分ですね。