pagination.phpを使ったページングに条件を追加する

http://bakery.cakephp.org/articles/view/paginationのpagination.phpを使ってページングさせている状態でロジックで必要な情報をGETパラメータに追加する方法とajaxを使って特定のdivタグの中を更新する方法です。

画面の動き

コードの説明の前に画面の構成です。

+-----------------------------------------------+
| +--------------+                               |
| |検索条件      |   +-------------------------+ |
| +--------------+   |  結果結果 (id="result") | |
| +--------------+   |                         | |
| | googlemap    |   |                         | |
| |              |   |                         | |
| |              |   |                         | |
| |              |   |                         | |
| |              |   |                         | |
| |              |   |                         | |
| +--------------+   +-------------------------+ |
+-----------------------------------------------+

拙い絵ですが、画面レイアウトです。簡単た仕様と想定している使い方は

  1. 検索条件のフォームへ$ajax->observeFormを使い検索結果がajaxで更新されるようにする
  2. 検索結果はpagination.phpでページングしておく
  3. 検索条件のテキストボックスに入力
  4. $ajax->observeFormがサーバへPOSTして、得られたコンテンツを検索結果のdivタグに反映
  5. 検索結果のページナビゲーションを使ってページの移動を行なう

ロジックに必要な情報を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を指定
);

Trackback URL

Leave a comment

Your comment