pagination.phpを使ったページングに条件を追加する
http://bakery.cakephp.org/articles/view/paginationのpagination.phpを使ってページングさせている状態でロジックで必要な情報をGETパラメータに追加する方法とajaxを使って特定のdivタグの中を更新する方法です。
画面の動き
コードの説明の前に画面の構成です。
+-----------------------------------------------+ | +--------------+ | | |検索条件 | +-------------------------+ | | +--------------+ | 結果結果 (id="result") | | | +--------------+ | | | | | googlemap | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +--------------+ +-------------------------+ | +-----------------------------------------------+
拙い絵ですが、画面レイアウトです。簡単た仕様と想定している使い方は
- 検索条件のフォームへ$ajax->observeFormを使い検索結果がajaxで更新されるようにする
- 検索結果はpagination.phpでページングしておく
- 検索条件のテキストボックスに入力
- $ajax->observeFormがサーバへPOSTして、得られたコンテンツを検索結果のdivタグに反映
- 検索結果のページナビゲーションを使ってページの移動を行なう
ロジックに必要な情報をGETパラメータに追加
ここで一番悩んだのは、フォームからPostするが、ページナビゲーションはGETで移動先のページへ遷移するために、POSTされた時はフォームへ入力された検索条件値がリクエストURLには含まれていないということ。そのため、pagination.phpが出力するナビゲーションにも検索条件値がふくまれていない。最初はコントローラで$this->dataに格納されている必要値を$this->params[’url’]に追加したが、app/controller/components/pagination.phpの中でURLの末尾に’/’が付けられてしまうためボツ。app/views/helper/pagination.phpのコード追いかけていくと、viewの先頭で呼ぶPaginationHelper::setPaging($paging) の中で$this->params[’url’]を保存しておき、PaginationHelper::_generateUrl($page=NULL,$pageDetails=NULL)がこの中身を使ってGETのURLを組み立てているのが判った。
これが判れば、コントローラの中でPOSTされた値を$this->dataから必要な値を$params->l;paramsへ写しておけばよい。PaginationHelper::_generateUrlがポストされた値も含めてGETのURLを組み立ててくれる。最後は、コントローラでPOSTとGETの両方をみてWHEREの条件を組み立てればよい。
/*
* GETパラメータ及びPOSTされたデータからWHERE句の条件を作る
*
* @param paramName パラメータ名。
* @param condition WHERE句の条件。sprintfで値を代入させる。
*
* @return 値がある場合は WHERE句の条件。値が無い場合はnull
*/
function buildWhere($paramName,$condition){
$result = null;
// GETの場合
if (isset($this->params['url'][$paramName]) &&
$this->params['url'][$paramName] != ''
) {
$param_var = $this->params['url'][$paramName];
// ページングにパラメータとして渡すためにurlパラメータに追加
$this->params['url'][$paramName]=urlencode($param_var);
// WHERE句を作成
$result = sprintf($condition,mb_convert_encoding(urldecode($param_var),"EUC-JP","UTF-8"));
}
// エリア指定 POSTの場合
if (isset($this->data['Hogemodel'][$paramName]) &&
$this->data['Hogetable'][$paramName] != ''
) {
// WHERE句を作成
$result = sprintf($condition, $this->data['Hogemodel'][$paramName]);
// ページングにパラメータとして渡すためにUTF-8に変換してURLエンコードした値をurlパラメータに追加
$this->params['url'][$paramName]=urlencode(urlencode(mb_convert_encoding($this->data['Hogemodel'][$paramName],"UTF-8","EUC-JP")));
}
function index(){
$param_var = $this->buildWhere("name","name= '%s'");
if ( $param_var != null ) {
array_push($where_params,$param_var);
}
// 配列に格納したWHEREの条件をANDで結合
$where = implode(" AND ", $where_params);
list($order,$limit,$page) = $this->Pagination->init( ~
以下省略
}
ajaxを使って特定のdivタグの中を更新
コントローラがPaginationComponent::initを呼ぶときの第3引数の連想配列にキーに’ajaxDivUpdate’、値にdivタグ名を入れる。
list($order,$limit,$page) = $this->Pagination->init(
$where
,Array()
,array(’ajaxDivUpdate’ => ‘result’) // prototyle.jsが更新するdivタグのidを指定
);
