Add Filter To Gridview With Custom Activedataprovider

Hello,

I’ve just started learning Yii, and am currently stuck with the following problem.

I have a tables Task and Solution with the following relation


'solutions' => array(self::HAS_MANY, 'Solution', 'task_id')

In "view" page for Task I have added a GridView that would list all related solutions (i.e. all solutions for that task) by setting an ActiveDataProvider that would fetch items by column value. That GridView is sortable, but I would also like to be able to filter it.

I can see that in “admin” a filter is added just by “‘filter’=>$model”, but since I use my own ActiveDataProvider, and $model would refer to the wrong model I’m not too sure how to proceed.

Here is the related code from Task view


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

	'data'=>$model,

	'attributes'=>array(

        'id',

        'topic.name',

		'difficulty',

		'description',

    ),

)); ?>


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

    'dataProvider'=>new CActiveDataProvider("Test",array

        (

            'criteria'=>array('condition'=>'task_id='.$model->id)

        )),

    'columns'=>array(

        'input',

        'output',

    ),

)); ?>




//this needs a filter

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

    'dataProvider'=>new CActiveDataProvider("Solution",array

        (

            'criteria'=>array('condition'=>'task_id='.$model->id)

        )),

    'columns'=>array(

        'student_id',

        'attempt_count',

        'last_attempt',

        'is_solved:boolean',

    ),

)); ?>

Hi i_like_pie, welcome to the forum.

You would need another model instance (e.g. $solutionModel) that is of Solution model, and let it create the data provider.

Probably something like the following:




//this needs a filter

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

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

    'filter' => $solutionModel,

    'columns'=>array(

        'student_id',

        'attempt_count',

        'last_attempt',

        'is_solved:boolean',

    ),

)); ?>

And in the controller:




public function actionView($id)

{

    $model = $this->loadModel($id);

    $solutionModel = new Solution('search');

    $solutionModel->unsetAttributes();

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

        $solutionModel->attributes = $_GET['Solution'];

    }

    $solutionModel->task_id = $id; // this will force Solution::search() to search

                                   // only the records with that task_id

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

        'model' => $model,

        'solutionModel' => $solutionModel,

    ));

}



And I hope the following wiki will be a help:

http://www.yiiframework.com/wiki/381/cgridview-clistview-and-cactivedataprovider/

Oh wow! That was much easier than I expected. Not sure why I didn’t think of just using a different model. Guess I am still a “bit” overwhelmed by all the stuff that can be done here.

Also, thank you for the controller example and wiki link. Using search that way makes much more sense than what I was trying to do.