Using CGridView filters with custom Criteria

Hello, I have a CGridView for my Engines table defined by:




$criteria = array('condition'=>'pid=208'); //custom criteria

$dp = new CActiveDataProvider('Engines', array(

	'criteria'=>$criteria

));


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

		'id'=>'engines-grid',

		'dataProvider'=>$dataProvider,

	        'filter'=>Engines::model(),

		'columns'=>array(

			'engine',

		$cbutton //custom buttons, ignore

	),

));



This works like a charm, everything displays beautifully. However, when I put some text in the CGridView filter, nothing happens. I see the ajax loading gif and then the text is cleared and nothing changes. Any ideas? By the way, even when I change dataProvider to Engines::model()->search() (I can’t just do $model->search() because this in contained in a widget in some other view) just for testing, it still does the same thing (i.e. nothing). Thanks.

I tried to explain my view of the auto generated code here. Perhaps it will help.

If you call the search metod on the class instance instead of the instance that harvested the posted filter values, you will always have the initial values from the first time the model was instantiated.

/Tommy

Sorry, it’s not sinking in very well. I’m guessing that the filter I use now (Engines::model()) is not taking into account my criteria of pid=208, so therefore something messes up when trying to filter. Do I have to create a custom filter or search? I just don’t get how to start setting up something like that. Thanks.

I don’t know enough about your use case but I would try something in line with this




$model = new Engines;

$model->unsetAttributes();

$model->pid = 208;


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

                'id'=>'engines-grid',

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

                'filter'=>$model,

                'columns'=>array(

                        'engine',

                $cbutton //custom buttons, ignore

        ),

));



(totally untested)

/Tommy

Hmm…it displays perfectly well and even sorts, but again when I enter something in the filter it just starts to work and then clears the field and nothing happens. It actually happens even when I don’t add the pid=208 line. This problem only seems to happen for me when I am using a CGridView outside of the normal controller. Meaning, I have a CGridView for Users on the views/users/admin page, which filters fine, but this CGridView is NOT in an Engine-related view. Here is my search function, from which I have commented out the PID stuff:




public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;

		//$criteria->with = array('program');

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

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

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

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

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

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

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

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

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

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

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

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

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


		return new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria,

		));

	}



Note that the only thing I really care about is the engine attribute, which is the name of the engine. Also, here is my CGridView, based on what you gave me, stripped of the PID and even custom buttons:




$model = new Engines;

$model->unsetAttributes();


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

	'id'=>'engines-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'engine',

	),

));



Even still it doesn’t work. Could this have something to do with the fact that this functionality is inside a widget which is called from a non-engine View? Thanks.

** I just checked firebug and it seems to be sending the request and receiving a response, so that’s working fine. It’s just the wrong response I guess.

I don’t know the answer, have to look into this myself some time.

This is what’s effectively takes place in the auto-generated actionAdmin and view. The CGridview use to be embedded in a form and the default action will be called on sort and search (IIRC).




$model=new Engines('search');

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

    

if(isset($_GET['Engines']))

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

	

//$model->pid = 208;


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

  'id'=>'engines-grid',

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

  'filter'=>$model,

  'columns'=>array(

    'engine',

  ),

));



I think you’ll have to figure out the best way to propagate the data from $_GET to your widget. That’s what I can think of for the moment, I’m sure there’s more to it.

/Tommy

Happy days are here again!!!!! Thanks, that line




if(isset($_GET['Engines']))

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



did the trick! I’m not sure why I didn’t include that to begin with because it is there in the default admin CGridViews. I’m not sure what it does, and when I tested the conditional with an echo “aaaaaaa”, nothing showed up, so it doesn’t even seem to be doing anything. However, obviously it’s necessary for some reason, but I’m just happy it’s working.

It sets each of the attributes in the model to equal the key of the same name in $_GET[‘Engines’].

It does get called, but you won’t see the echo during an ajax call, which is what CGridView does when you interact with it. Instead try logging something inside your if statement, and you’ll see a result.

@story note that you are responding to a post more than a year old…

Yeah, I just figured that someone might be viewing this post to gain a better understanding of Yii, so better to not leave them hanging like that.