Question

I want to do something very straight forward and simple. I want to have two different sets of paginated data on the same page. The two different sets depend on different models. For discussion's sake we'll say they are Image and Item.

I can set up two pagers for two models, and get the correct set of objects. I can get the correct pager links. But when it comes to actually following the links to the parameters, both pagers read the parameters and assume they apply to them.

It winds up looking something like this:

   $this->paginate = array (
        'Item'=>array(
            'conditions'=>array('user_id'=>$id),
            'limit' => 6, 
            'order' => array(
                'Item.votes'=>'desc', 
                'Item.created'=>'desc'
            ),
            'contain'=>array(
                'User', 
                'ItemImage' => array (
                    'order'=>'ItemImage__imageVotes desc'
                )
            )
        ),
        'Image'=>array(
            'limit'=>6,
            'contain'=>array(
                'User',
                'ItemImage'=>array('Item'),
            ),
            'order'=>array(
                'Image.votes'=>'desc',
                'Image.views'=>'desc'
            ),
            'conditions'=>array(
                'Image.isItemImage'=>1,
                'Image.user_id'=>$id
            )
        )
    );
    $this->set('items', $this->paginate('Item'));   
    $this->set('images', $this->paginate('Image'));

That's in the controller. In the view I have sort links that look like this:

<div class="control"><?php echo $this->Paginator->sort('Newest', 'Image.created', array('model'=>'Image')); ?></div>

However, that yields a link that looks like this:

http://localhost/profile/37/page:1/sort:Image.created/direction:asc

There's nothing in there to tell the paginator which model I intend to sort. So when I click on the link it attempts to sort both models by Image.created. The result is an error, because Item cannot be sorted by Image.created. Is there something I'm doing wrong? Or is this something that isn't supported by CakePHP's paginator?

Was it helpful?

Solution

The easiest solution would be to implement both grids as elements that fetch their own data and use AJAX to load the elements into the page.

The only other option would be to modify the params so you pass the params for both grids to each grid when sorting or stepping through pages. The code posted by Leo above is a good start. You can prepend the Model key from the paginate array onto each named param and make sure you pass all url params to the paginate function and you should be headed in the right direction.

OTHER TIPS

You'll need to override the paginate method for the Model of the Controller of that page.

I did something similar, maybe this snippet will help:

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array())
{
    $pageParams = compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive', 'group');
    $this->contain('ModuleType', 'NodeDescriptor');
    $pageItems = $this->find('all',$pageParams);
    $pagesOut = array();
    foreach($pageItems as $pageItem)
    {
        $status = $pageItem['SiteAdmin']['status_id'];
        $moduleInfo = null;
        $nodeTitle = $pageItem['NodeDescriptor']['title'];
        $published = $pageItem['NodeDescriptor']['published'];
        $pageitemID = $pageItem['SiteAdmin']['id'];
        $moduleId =  $pageItem['SiteAdmin']['module_id'];
        $contName =  $pageItem['ModuleType']['controller'];
        if($moduleId)
        {
            $thisModel = ClassRegistry::getObject($moduleType);
            $thisModel->contain();
            $moduleInfo = $thisModel->read(null,$moduleId);
            $moduleInfo = $moduleInfo[$moduleType];
        }
        $pagesOut[] = array(
            'status'=>$status,
            'node'=>$nodeTitle,
            'published'=>$published,
            'info'=>$moduleInfo,
            'module_id'=>$moduleId,
            'contName'=>$contName,
            'pageitem_id'=>$pageitemID);
    }
    return $pagesOut;
}

By doing it this way, you gain control over the parameters passed to paginate, so you can pass model specific data, control flags etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top