LoginSignup
3
6

More than 5 years have passed since last update.

[俺の備忘録シリーズ] DataTablesを使ってサーバーサイドのページネーション

Posted at

準備

CakePHP2でAjaxでjson使うので、.jsonでアクセス出来るようにする

route.php
Router::parseExtensions('json');

jsを読み込む

index.ctp
<?= $this->Html->script('https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js') ?>

クライアントサイド実装

とりあえず、Userテーブルの名前だけを出す感じのTableをコーディング

index.ctp
<table id="table">
    <thead>
        <tr>
            <th>名前</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

サーバーサイドでページネーションをする場合は、serverSideをtrueにする

index.ctp
$(document).ready(function() {
    $('#table').DataTable({
        "ajax": "/hoge/read_users.json",
        "dataSrc": "data",
        "columns": [
            { data: "name" },
        ],
        "serverSide": true,
    });
});

サーバーサイド実装

Ajax使うので、コントローラにRequestHandlerを追加

HogeController.php
var $components = ['RequestHandler'];

メソッドの追加

HogeController.php
public function read_users() {
  if (!$this->request->is('ajax')) {
    throw new BadRequestException('そこはダメよ!');
  }
  $this->response->header('X-Content-Type-Options', 'nosniff');
  // 単独テーブルアクセス
  $options = [
    'recursive' => -1,
  ];
  // 全件数取得
  $count = $this->User->find('count', $options);
  // クライアントから送られてきたページ位置をセット
  $options['offset'] = $this->request->query('iDisplayStart');
  $options['limit'] = $this->request->query('iDisplayLength');
  $options['page'] = 0;

  $data = $this->User->find('all', $options);
  // TODO: エラー処理
  $data = Hash::extract($data, '{n}.User');

  $this->set('draw', $this->request->query('sEcho'));
  $this->set('recordsTotal', $count);
  $this->set('recordsFiltered', $count);
  $this->set('data', $data);
  $this->set('_serialize', [ 'draw', 'recordsTotal', 'recordsFiltered', 'data' ]);
}
3
6
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
3
6