CakePHP1.3.6:ページネーション(Pagination)。
CakePHPで秀逸だなぁと思うのが、このページネーション。とってもスマートに書くことができる。Myznalaでもオレオレ流のページネーションを提供しているが、自分で書くとなるとそれなりに面倒くさい。
CakePHPでは、一覧表示画面に簡単なコードを追加するだけで、
- ページの区切り
- 前後のページへの移動
- 特定のページへのジャンプ
- 見出しクリックによるソート
ができてしまう。素晴らしい!!
前回のログのコードをベースに上の機能を追加する。コントローラーとindexアクションのテンプレート(index.ctp)を変えるだけでよい。
コントローラーの変更
$paginateというメンバー変数にオプションを定義する。
Sort+Directionというオプションがあるようだが動かないので、orderオプションで指定した。
修正するアクションはindexのみ。
<?php require_once '../vendors/MyConverter.class.php'; class CustomersController extends AppController{ public $name = 'Customers'; public $layout = 'myznala'; /* * Paginatorの定義 */ public $paginate = array( 'page'=>1, 'conditions'=>array(), 'fields'=>array('id','name','zip','address','tel','timestamp'), 'order'=>array('timestamp'=>'desc'), 'limit'=>5, 'recursive'=>0 ); /** * * 初期画面(一覧表示) */ function index(){ $this->set('title_for_layout', "顧客の一覧"); $req=null; if(!empty($this->data)){ //サニタイズ $req = MyConverter::getRequestParams($this->data["Customer"]); //絞り込みの場合には、コンディションを書き換える。 $this->paginate['conditions'] = array('Customer.name like ?' => array("%{$req["name"]}%")); } $data = $this->paginate(); $this->set('data',$data); } /** * * データの追加 * */ function add(){ $this->set('title_for_layout', "顧客の登録"); if(!empty($this->data)){ // サニタイズ $this->data["Customer"] = MyConverter::getRequestParams($this->data["Customer"]); // 登録 $this->Customer->save($this->data); if($this->Customer->validates()){ // 登録できたらリダイレクト $this->redirect('.'); } } } /** * * データの照会 * $paramsにIdが入ってくる。 * */ function show($param){ $this->set('title_for_layout', "顧客の詳細"); $result=null; if(!empty($param)){ // Idフィールドによる検索 $this->data=$this->Customer->findById($param); if(!$this->data){ // 存在しないIDを参照された場合。 $this->Session->setFlash('存在しません'); $this->redirect('.'); } } $this->set('data',$this->data); } /** * * データの更新 * */ function edit($param){ $this->set('title_for_layout', "顧客情報の更新"); // データの更新 if(!empty($this->data)){ // サニタイズ $this->data["Customer"] = MyConverter::getRequestParams($this->data["Customer"]); // Idフィールドによる検索 $check=$this->Customer->findById($param); if(!$check){ // 存在しないIDを更新しようとした場合。 $this->Session->setFlash('存在しません'); $this->redirect('.'); }else{ // 更新 $this->Customer->save($this->data); if($this->Customer->validates()){ // 更新できたらリダイレクト $this->redirect('.'); } } // 更新データのセット(初期値) }else{ if(!empty($param)){ // Idフィールドによる検索 $check=$this->Customer->findById($param); if(!$check){ // 存在しないIDを更新しようとした場合。 $this->Session->setFlash('存在しません'); $this->redirect('.'); }else{ // Idフィールドによる検索 $this->data=$this->Customer->findById($param); } } } // エラーの場合も通るようにする $this->set('data',$this->data); } /** * * データの削除 * */ function delete($param){ if(!empty($param)){ $check=$this->Customer->findById($param); if(!$check){ // 存在しないIDを削除しようとした場合。 $this->Session->setFlash('存在しません'); }else{ // Idフィールドによる削除 $this->data=$this->Customer->delete($param); } $this->redirect('.'); } } } ?>
ビューの修正
index.ctpを以下のように修正する。
どうも、customersを最初に呼び出したときに、照会ページと登録ページへのアンカーからcustomersが抜けてしまう(ページネータを使う前から)。
そこで、アンカーをHTMLヘルパーで生成するようにしてみた。
<h2>顧客の一覧</h2> <br> 名前で絞り込みをします。 <?php // 絞り込み用フォーム echo $form->create('Customer',array('type'=>'post','action'=>'.')); echo $form->text('Customer.name', array('size' => 10)); echo $form->end('送信'); ?> <?php // ページネーション echo $paginator->numbers( array( 'before'=>$paginator->hasPrev() ? $paginator->first('<<').' ' : '', 'after'=>$paginator->hasNext() ? ' '.$paginator->last('>>') : '', 'modulus'=>4, 'separator'=>' ' ) ); ?> <table> <tr> <th><?php echo $paginator->sort('ID','id') ?></th> <th><?php echo $paginator->sort('名前','name') ?></th> <th><?php echo $paginator->sort('郵便番号','zip') ?></th> <th><?php echo $paginator->sort('住所','address') ?></th> <th><?php echo $paginator->sort('電話','tel') ?></th> <th><?php echo $paginator->sort('更新日','timestamp') ?></th> </tr> <?php foreach ($data as $arr){ echo '<tr>'; echo '<td>'.$html->link($arr['Customer']['id'], array('controller'=>'customers', 'action'=>'show',$arr['Customer']['id'])).'</td>'; echo "<td>{$arr['Customer']['name']}</td>"; echo "<td>{$arr['Customer']['zip']}</td>"; echo "<td>{$arr['Customer']['address']}</td>"; echo "<td>{$arr['Customer']['tel']}</td>"; echo "<td>{$arr['Customer']['timestamp']}</td>"; echo '</tr>'; } ?> </table> <?php echo $html->link('登録', array('controller'=>'customers', 'action'=>'add')); ?>