Tuesday, July 3, 2012

Paginating and sorting data in YII framework

In latest Yii releases, accent was moved from using Active Record directly to grids, lists, and
data providers. Still, sometimes it is better to use active record directly. Let's see how to list
paginated AR records with ability to sort them.
Getting ready
1. Setup a new application using yiic webapp.
2. Create a database structure table post with id and title fields, add 10—20
records.
3. Generate Post model using Gii.
How to do it...
1. First, you need to create protected/controllers/PostController.php:
class PostController extends Controller
{
function actionIndex()
{
$criteria = new CDbCriteria();
$count=Post::model()->count($criteria);
$pages=new CPagination($count);
// elements per page
$pages->pageSize=5;
$pages->applyLimit($criteria);
// sorting
$sort = new CSort('Post');
$sort->attributes = array(
'id',
'title',
);
$sort->applyOrder($criteria);
$models = Post::model()->findAll($criteria);
$this->render('index', array(
'models' => $models,
'pages' => $pages,
'sort' => $sort,
));
}
}
2. Now, let's implement protected/views/post/index.php as follows:
<p><?php echo $sort->link('id')?></p>
<p><?php echo $sort->link('title')?></p>
<ol>
<?php foreach($models as $model):?>
<li>
<h2><?php echo $model->id?> - <?php echo $model->title?></h2>
</li>
<?php endforeach?>
</ol>
<?php $this->widget('CLinkPager', array(
'pages' => $pages,
))?>
3. Try to load http://example.com/post. You should get a working pagination and
links that allow sorting list by ID or by title.
How it works...
First, we get total models count and initialize new pagination component instance with it.
Then, we use the applyLimit method to apply limit and offset to criteria we have used for
count request. After that, we create sorter instance for the model, specifying model attributes
we want to sort by and applying order conditions to criteria by calling applyOrder. Then, we
pass modified criteria to findAll. At this step, we have models list, pages, data used for link
pager, and sorter that we use to generate sorting links.
In a view, we are using data we gathered. First, we are generating links with CSort::link
method. Then, we are listing models. Finally, using CLinkPager widgets we are rendering
pagination control.

1 comment:

  1. This will not work, because you are retrieving all the data in your model and looping through it. There is no relationship between your model and the paging object.

    ReplyDelete