Edited at

jquery.datatable.js で 入力したページ番号にジャンプする機能を実装する


デモ

https://codepen.io/qwe001/pen/OYWpQx

画面下部にあるページネーションの「 」 のリンクをクリックしたら、入力画面が表示されます。

そこに半角数字で値を入れたら、指定したページ番号に一致するレコードを表示します。


何がしたいか

image.png

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ページ分ですね。