0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-05-15

デモ

画面下部にあるページネーションの「 」 のリンクをクリックしたら、入力画面が表示されます。
そこに半角数字で値を入れたら、指定したページ番号に一致するレコードを表示します。

何がしたいか

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

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?