Hi,
it’s a little too complicated for my taste, but i’ll summarize here the way searching is used in yiis blog demo.
First of all there is a CGridView inside posts admin view:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
array(
'name'=>'title',
'type'=>'raw',
'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'
),
array(
'name'=>'status',
'value'=>'Lookup::item("PostStatus",$data->status)',
'filter'=>Lookup::items('PostStatus'),
),
array(
'name'=>'create_time',
'type'=>'datetime',
'filter'=>false,
),
array(
'class'=>'CButtonColumn',
),
),
)); ?>
You can ignore the columns-array at the moment
$model is a ‘Post’ model (you’ll see it inside the controller). As you can see it’s assigned to the filter attribute of CGridView AND the search() function of this model is used as source for the dataProvider.
The filter-property is only used as reference to the model needed for generating ‘active’ form elements in filter cells (like an activeDropDownList instead of a input-element for filtering).
Next let’s take a look inside the ‘Post’ model, where we can find a (new) function called search():
/**
* Retrieves the list of posts based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the needed posts.
*/
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('title',$this->title,true);
$criteria->compare('status',$this->status);
return new CActiveDataProvider('Post', array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'status, update_time DESC',
),
));
}
This function is used as a source for CGridViews dataProvider so it needs to return an CActiveDataProvider.
The search attributes (here: title and status) are added to the CDbCriteria using compare() and as you can see from e.g. "$this->title" we need to have an instance of your model where we have assigned the search-values as property-values.
This instance is created and filled inside the controller:
/**
* Manages all models.
*/
public function actionAdmin()
{
$model=new Post('search');
if(isset($_GET['Post']))
$model->attributes=$_GET['Post'];
$this->render('admin',array(
'model'=>$model,
));
}
As you see there is no magic in here. We’re creating a Post-object (with scenario ‘search’) and we assign the $_GET[‘Post’]-values (which are the values of the searchfields) as attributes.
Inside the model you may add
array('title, status', 'safe', 'on'=>'search'),
to rules() to define these attributes to be safe for searching.
That’s it.
A little addition: afaik you can not use single side placeholders like “WHERE Name LIKE ‘Foo%’” using $criteria->compare(), but i think it’s very useful.
Therefore i’m using this instead:
if($this->title !== '')
$criteria->addSearchCondition('Title',$this->title.'%',false);
Regards