CListView and Pagination

On my search results page I display results from 3 different models. These are displayed in their own containers on the page using CListView widgets.

Now I am using POST as the submit method for the query form. I wish to use the ajax style pagination to browse through the search results. However I am having problems with this, I think maybe to do with the fact I am using POST.

What is the correct method of implementing ajax style pagination on CGridView? Also how can we ensure that when the user clicks into a result and then clicks back, they are taken back to their previous page number?

Here is my SearchController:




public function actionIndex()

{

	if(isset($_POST['search']))

	{

		$dataProvider1=new CActiveDataProvider('Product', array(

			'criteria'=>array(

				'condition'=>'active=1 AND prod_name LIKE :prod_name',

				'params'=>array(':prod_name'=>"%{$_POST['search']}%"),

			),

			'pagination'=>array(

				'pageSize'=>10,

			),

		));

		

		$dataProvider2=new CActiveDataProvider('Event', array(

			'criteria'=>array(

				'condition'=>'published=1 AND title LIKE :title',

				'params'=>array(':title'=>"%{$_POST['search']}%"),

			),

			'pagination'=>array(

				'pageSize'=>10,

			),

		));

		

		$dataProvider3=new CActiveDataProvider('News', array(

			'criteria'=>array(

				'condition'=>'published=1 AND title LIKE :title',

				'params'=>array(':title'=>"%{$_POST['search']}%"),

			),

			'pagination'=>array(

				'pageSize'=>10,

			),

		));

			

		$this->render('index', array(

			'dataProvider1'=>$dataProvider1,

			'dataProvider2'=>$dataProvider2,

			'dataProvider3'=>$dataProvider3,

		));

	}

}



And my view (views/search/index.php):




<div id="product-categories">


<h1>Products</h1>


<?php $this->widget('zii.widgets.CListView', array(

	'dataProvider'=>$dataProvider1,

	'itemView'=>'_view_products',

)); ?>


</div>



I think I got my answer… I changed the form method to GET and it seems to be working fine now.

Only problem is regarding the last point - "how can we ensure that when the user clicks into a result and then clicks back, they are taken back to their previous page number?"

I solve by passing the number of page to the action that shows a result, and then back.

The link for go in the result change from this




CHtml::link($model->id, array('show', id=>$model->id));



to this




CHtml::link($model->id, array('show', id=>$model->id, 'page'=>$dataProvider->pagination->currentPage));



And in the view of result, you can do the lik for back like that:




CHtml::link('back', array('list', 'page'=>$_GET['page']));



You can use instad of this last one ‘page’ the same get var that CPagination uses, or you can set the page manually in the action




actionList()

{

   $dataProvider->pagination->currentPage=$_GET['page'];

}



If you are using ajax or submit button, you have to change the link accordigly.

Is a bit strange to send a get var ‘page’ to a page that has no pager (shows). If you so much don’t like it you can send by post.

Thanks zaccaria, very helpful!

Do you know how I can display a pager at the top of the resultset, as well as at the bottom?

Anyone able to advise on the above?

EDIT: I found the answer:

‘template’=>’{summary}{pager}{items}{pager}’,

Hi,

I think you have a little mistake, because the value of $_GET[‘page’] is one-based while the value of $dataProvider->pagination->currentPage is zero-based.

I would have expected that $_GET[‘page’] would have been one-based but I verified it wasn’t.

By the way, you can get the name of the $_GET variable containing the current page as follows:

$dataProvider->getPagination()->pageVar