views:

253

answers:

3

Hi, I have no idea how handle this two separate paginations in the view. Thanx for helping.

Controller code:

[...]
$this->Post->bindModel(array(
'hasAndBelongsToMany'=>array('Tag'),
'belongsTo'=>array('User')),false);
if($this->Session->check('Auth.User.id'))
  $this->Post->bindModel(array(
  'hasMany'=>array(
    'UserVote'=>array('conditions'=>array('UserVote.user_id'=>$this->Session->read('Auth.User.id') )),
    'Favorite'=>array('conditions'=>array('Favorite.user_id'=>$this->Session->read('Auth.User.id') ))
  )), false);


$posts = $this->paginate($this->Post,array('Post.public'=>1,'Post.user_id'=>$uid));

$posts2 = $this->paginate($this->Post,array('Post.public'=>0,'Post.user_id'=>$uid));


$this->set('posts',$posts);
$this->set('posts2',$posts2);

[...]
A: 

As the Pagination helper relies on the $controller->pagination field I think this is impossible. A quick hack would be to convert one or both of the paginations to Ajax-based ones. The pagination helper works very well with the Ajax helper.

matiasf
A: 

Is it a good idea to have two separate paginations on a page? It looks like You're trying to paginate through public posts and non-public posts - which surely can't be done at the same time? I.e. the user won't ever be on page 3 of the public posts and page 2 of the non-public posts at the same time. The only case this would really work is via AJAX with the pagination occouring in page as suggested by matiasf.

Would it not be a better solution to just show the first x public and non public posts in the current view and create a new view to show the pagination for each accessed by a link e.g. "view all public posts" and "view all non public posts"?

Loftx
+1  A: 

Even though in most cases a right solution would be to rearchitect your UI to remove the need for double pagination, the following is a working solution:

First, in your controller you override Cake's paginate() function to look for paginator key:

    /**
     * Handles automatic pagination of model records.
     *
     * @param mixed $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
     * @param mixed $scope Conditions to use while paginating
     * @param array $whitelist List of allowed options for paging
     * @return array Model query results
     * @access public
     * @link http://book.cakephp.org/view/165/Controller-Setup
     */
     function paginate($object = null, $scope = array(), $whitelist = array(), $key = null) {
      $results = parent::paginate($object, $scope, $whitelist);
      if ($key) {
       $this->params['paging'][$key] = $this->params['paging'][$object];
       unset($this->params['paging'][$object]);
      }

      return $results;
     }

Then

   /**
    * undocumented function
    *
    * @param string $key 
    * @return void
    * @access public
    */
     function _pageForPagination($by) {
       $page = 1;
       $samekey = isset($this->params['named']['by']) && $this->params['named']['by'] == $by;
       $pageInUrl = isset($this->params['named']['page']);
       if ($samekey && $pageInUrl) {
         $page = $this->params['named']['page'];
       }

       $this->passedArgs['page'] = $page;
       return $page;
     }

        /**
     * FIXME: Wrapper for Cake's pagination
     * Change pagination criteria on the fly (conditions, grouping, order, limit)
     *
     * @param string $model 
     * @param string $criteria 
     * @return void
     * @author Andrew
     */
     function _paginateBy($key) {
      $this->User->unbindModel(array('hasMany' => array('UserImage')), false);
      $this->paginate['User'] = am($this->User->getCriteria($key), array('page' => $this->_pageForPagination($key)));
      return $this->paginate('User', array(), array(), $key);
     }

Then use it like so in the controller: $this->set('byJoinDate', $this->_paginateBy('random'));

In the model: echo $paginator->prev('prev', array('model' => $by, 'class' => 'back'), null, array('model' => $by, 'class' => 'disabled back'));

Andrew Kolesnikov