Gridview - Filter Limited Set Of Results

Suppose I want to retrieve the last ten records in my database table.

I then want the filtering / sort to apply ONLY to these ten records (using CGridView).

How is this possible? I have tried the following:




public function search()

{

	$criteria = new CDbCriteria;

	$criteria->condition = 'status = 200';

	$criteria->order = 'created_at DESC';

	$criteria->limit = 10;

	

	$criteria->compare('name', $this->name, true);

	// etc

	

	return new CActiveDataProvider($this, array(

		'criteria'=>$criteria,

		'pagination'=>false,

	));

}



Whenever I apply a filter or sort, it brings back a different set of results.

Any ideas anyone?

How can I get the last 10 records from the table and use the filters on only those 10 records?

What is your code for the CGridView? It sounds like the issue is what you are passing to the filter parameter.

It is just the regular code, e.g:




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

	'id'=>'listing-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		//columns

	),

)); ?>



What is the code for the controller action? That is, what controller and what action does this grid appear on? I ask as that is what the grid calls when it needs to perform an update and by default, when you click on either a pager item or column header, it will go and fetch updated data!

So, say that you have a controller and model User with an action of List. In your view for this action, you want to limit it to only the 10 mostly recently added users.

Then, in your User::actionList() method, you need to handle generating the appropriate models.

We know this because according to the docs and source, the grid is going to call the source controller/action to update it’s data.

This is from the CGridView JavaScript source for the update function:




/**

 * Performs an AJAX-based update of the grid view contents.

 * @param options map the AJAX request options (see jQuery.ajax API manual). By default,

 * the URL to be requested is the one that generates the current content of the grid view.

 * @return object the jQuery object

 */



Although you set the initial contents of the grid by calling the search() method The Grid is going to be calling mysite/user/list?User_Attr1=FilterVal1&User_Attr2=FilterVal2&etc… every time it needs to update the grid, ie, whenever you sort the grid or page through the contents.

Therefore, in my User::actionList() method, I might have something like this:




    /**

     * Manages the ten oldest users with a status of 200

     */

    public function actionList()

    {

        $model = new User('search');

        $model->unsetAttributes();  // clear any default values

            

        if(isset($_GET['User'])) {

            $model->attributes = $_GET['User'];

        }


        $criteria = new CDbCriteria;

        $criteria->condition = 'status = 200';

        $criteria->order = 'created_at DESC';

        $criteria->limit = 10;


        // regardless of the filter, always apply this criteria!!!!

        $model->dbCriteria = $criteria;


        $this->render(

                'admin',

                array(

                    'model' => $model,

                )

        );

    }



One thing to note is that the CGridView is going to overwrite the LIMIT that we set. It does this as it uses the LIMIT clause for pagination purposes. Therefore, in order to really limit the intended result to no more than we specify, we have to modify the criteria such that it will never return more than our limit.

I hope this helps you out!!!

Basically I need to use a subquery for this to work. Something like:


SELECT * FROM

      (SELECT * FROM `listing` WHERE status = 200 ORDER BY created_at DESC LIMIT 10) tbl

WHERE ...

How can I integrate a subquery in to my existing code?

I am still pretty new to Yii myself but I believe this stackoverflow post will help http://stackoverflow.com/questions/8467698/sub-queries-activerecord-yii

Also, I recommend taking a look at this forum post about updating the cgridview http://www.yiiframework.com/forum/index.php/topic/31221-how-to-update-cgridview-with-ajax/. Its a little off-topic but I think you will find it enlightening on how the gridview actually works.

Hope this helps.