Zend_Paginatorでページネーション

多数のデータを、ページ分けして表示するための機能が『ページネーション』です。Googleで検索すると下の方に次のページへ移動するためのリンクが表示されますが、これが『ページネーション』です。ZendFrameworkには、ページネーションのために、『Zend_Paginator』というクラスが用意されています。今日は、この『Zend_Paginator』について調べてみたいと思います。

1) TestController.phpを修正して、ページネーションを作成してみます。まず、Zend_Paginatorをロードします。

Zend_Loader::loadClass(‘Zend_Paginator’);

2) indexActionを修正します。まず、Zend_Paginatorのインスタンスを取得します。インスタンスの取得は、Zend_Paginator::factoryを使います。

$result=Zend_Paginator::factory($result);

3) setItemCountPerPageで、表示する項目数を設定します。引数に1ページあたりの項目数を指定します。

$result->setItemCountPerPage(5);

4) 表示するページ番号をSetCurrentPerPageで指定します。送信されたpageパラメータを引数に渡します。

$result->setCurrentPageNumber($this->getRequest()->getParam(‘page’));

5) それではブラウザで確認してみます。『zend.winroad.info/test/index/page/2』と入力してみます。全レコードの2ページ目(項目数を5ずつにしていますので、6レコード目から10レコード目)を表示しています。

ページ移動用のリンク作成

6) とりあえず、ページ分けして表示するところまでは出来ましたが、アドレスにpageパラメータを直接入力して表示する人はまずいないでしょう。ページ移動用のリンクを作成したいと思います。

7) ビューに用意されている機能(ヘルパー)を使って、ページ移動用のインクを作成したいと思います。まず、ページ移動用のリンクをパーシャルとして用意して、これを読み込んで自動的にリンクを生成したいと思います。

8) 『views/Scripts』フォルダ内に新たに、『partials』フォルダを作成し、『pagination-pertial.phtml』ファイルを作成します。下記のように記述します。

<?php
 //前ページがあれば
 if(isset($this->previous)){
 echo "<a href=\"{$this->url(array('page'=>$this->first))}\">&lt;&lt;</a>&ensp;";
 //前ページがなければ
 }else{
 echo "<span style=\"color: #666666;\">&lt;&lt;</span>&ensp;";
 }
//前ページがあれば
 if(isset($this->previous)){
 echo "<a href=\"{$this->url(array('page'=>$this->previous))}\">&lt;</a>&ensp;";
 //前ページがなければ
 }else{
 echo "<span style=\"colro:#666666;\">&lt;</span>&ensp;";
 }
 //次ページがあれば
 if(isset($this->next)){
 echo "&ensp;<a href=\"{$this->url(array('page'=>$this->next))}\">&gt;</a>";
 //次ページがなければ
 }else{
 echo "&ensp;<span style=\"color:#666666;\">&gt;</span>";
 }
 //次ページがあれば
 if(isset($this->next)){
 echo "&ensp;<a href=\"{$this->url(array('page'=>$this->last))}\">&gt;&gt;</a>";
 //次ページがなければ
 }else{
 echo "&ensp;<span style=\"color:#666666;\">&gt;&gt;</span>";
 }

8) index.phtmlファイルの下のほうに、パーシャルを読み込み、レンダリングするためのpaginationControlというメソッドを作成します。

paginationControl(アダプターインスタンス,形式,パーシャル)

9) これで、指定したパーシャルを読み込み、アダプターのインスタンスから必要な情報を取得し、現在のページに合わせたページリンクが表示されるようになります。

10) 修正後のindex.phtmlを下記に表示します。

<div class="content">
<h3>DVDコレクション</h3>
<p>タイトル名かコンテンツの内容で検索できます</p>
<form id="form1" name="form1" method="post" action="">
<table border="0">
 <tr>
 <th scope="row">曖昧検索</th>
 <td><label for="title"></label>
 <input name="search" type="text" /></td>
 <td><input type="submit" name="button" value="検索" /></td>
 </tr>
 </table>
</form>
<hr />
<table width="100%" border="1">
 <tr>
 <th scope="col">ID</th>
 <th scope="col">Title</th>
 <th scope="col">Content</th>
 <th scope="col">処理</th>
 </tr>
 <?php foreach($this->result as $row):?>
 <tr>
 <td><?=$row['id']?></td>
 <td><?=$row['title']?></td>
 <td><?=$row['content']?></td>
 <td><a href="<?=$this->url?>/test/edit/id/<?=$row['id']?>">更新</a>
  <a href="<?=$this->url?>/test/del/id/<?=$row['id']?>">削除</a></td>
 </tr>
 <?php endforeach;?>
</table>
<?=$this->paginationControl($this->result,'Sliding','/partials/pagination-partial.phtml');?>
<p><a href="<?=$this->url?>/test/add">新規入力</a></p>
</div>

11) ブラウザで確認してみます。ページネーションリンクが表示されました。

12) リンクをクリックするとページが移動します。ブラウザで直接入力するのと同じ動作をします。

ページ番号によるリンク

13) 次は、googleみたいにページ番号によって簡単にページを移動できるようにしてみたいと思います。pagination-partial.phtmlを修正します。

14) 『pagesInRange』は、表示する範囲のページ番号を配列でまとめたものが保管されています。この配列を順に書き出すことで、ページ番号のリンクを作成できます。

foreach($this->pagesInTage as $page){

15) 現在表示されているページ番号を示すメンバー変数『current』を使い、現在表示されているページ番号だけにリンクを付けないようにします。

if($page != $this->current){

16) 修正したpagination-partial.phtmlを下記に表示します。

<?php
//表示する範囲の分だけ繰り返し
foreach($this->pagesInRange as $page){
 //現在表示中のページ番号でなければリンクを付与
 if($page != $this->current){
 echo "<a href=\"{$this->url(array('page'=>$page))}\">{$page}</a>&ensp;";
 //現在表示中のページ番号を表示(リンクは付けない)
 }else{
 echo "{$page}&ensp;";
 }
}

17) TestController.phpのindexActionに『setPageRange』で、表示するページの範囲を5に指定します。

$result->setPageRange(5);

18) 修正したindexActionを下記に表示します。

public function indexAction(){
 //データベースからレコードを取得する
 $result=$this->Dvdcollections->searchAll();

 //POST送信された場合の処理
 if($this->getRequest()->isPost()){
 //受け取った値を変数に代入する
 $search=$this->getRequest()->getParam('search');
 //タイトルとコンテンツで曖昧検索する
 $result=$this->Dvdcollections->orSearch($search);
 }
 //Zend_Paginatorのインスタンス取得
 $result=Zend_Paginator::factory($result);
 //表示項目数の設定
 $result->setItemCountPerPage(5);
 $result->setCurrentPageNumber($this->getRequest()->getParam('page'));
 //表示するページ番号の範囲を指定
 $result->setPageRange(5);
 //連想配列データベース情報をセット
 $this->view->assign('result',$result);
 }

19) ブラウザで確認してみます。表示されたページネーションの5ページ目をクリックしてみます。

20) 2ページ目から6ページ目のページ番号が表示されています。

スクロール形式の違い

21) ページ番号を使って表示させる場合、paginationControllの第2引数にスクロールの形式を指定することで、表示方法が変わります。スクロール形式にはどんなものがあるのか調べてみます。

  • Sliding
    現在使用しているスクロール形式が 『Sliding』です。これは、現在表示されているページの前後のページを表示する形式です。
  • All
    全てのページを表示する形式です。
  • Elastic
    Google風のページ表示を行うものです。たとえば5ページを表示する場合、1ページ目では、1~5が表示され、ページが進むにつれてページが増えいき、5ページ目では、1~9ページが表示されます。その後、移動するたびに前のページが消えていきます。後で、どのような表示になるのか試してみます。
  • Jumping
    一定範囲を表示し、それを超えると丸ごとページ番号が変わるスクロール形式です。表示ページが5ページの場合、1~5、6~10、11~15というように、5ページごとにひとまとまりとして表示されます。

22) それでは、実際にスクロール形式をElasticにしたらどのように表示されるのか見てみたいと思います。只、入力データ数がそんなに多くないので、1ページの表示数を3、表示するページ範囲を3に変更してみました。

23) 最初は、1~3ページ目までが表示されていました。2ページ目をクリックしてみます。

23) 4ページ目が増えました。

24) 3ページ目をクリックすると、5ページ目が増え1~5ページまでを表示します。しかし、4ページをクリックすると、6ページ目が増えましたが、1ぺーじ目が消えています。

本日は、以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

コメントをどうぞ

このページの先頭へ