Difference between #5 and #4 of Using standard filters in CGridView custom fields

unchanged
Title
Using standard filters in CGridView custom fields
unchanged
Category
How-tos
unchanged
Tags
CGridView, interface, filters, search
changed
Content
In this article I'll try to explain how to use standard quick search fields in
CGridView with customized columns.  
**For example:**  
We have a record in a database with field `switch` having 0 or 1 values.
After that we want a user to see `on` or `off` instead 1 or 0.  
So we do the usual thing:
~~~
[php]
<?php $this->widget('zii.widgets.grid.CGridView', array(
//.....
array('name'=>'switch','header'=>'Switch','type'=>'raw','value'=>'Mii::getSwitch($data->switch)'),array(
    'name'=>'switch',
    'header'=>'Switch',
    'type'=>'raw',
    'value'=>'Mii::getSwitch($data->switch)'
),
//.....
	),
)); 
~~~
`Mii::getSwitch` - is my own helper witch returns `on` or `off` according to the
current switch value (in the original it returns an image).  
After that the user can see `on` and `off` values in the column, but he will not
be able to filter columns typing `on` or `off` in the quicksearch field.  
So we do the following thing in model `search()` function:
~~~
[php]
public function search()
{
    // Warning: Please modify the following code to remove attributes that
    // should not be searched.
    $criteria=new CDbCriteria;
    //....other fields
    $criteria->compare('switch',$this->getSwitch($this->switch));
    return new CActiveDataProvider(get_class($this),
array('criteria'=>$criteria,));
}

//function that returns usual 0 or 1 value dependently user input
public function getSwitch($switch)
{
    if(is_null($switch)) return $switch; //null shows all records
    if(is_numeric($switch)) return $switch; //here we save an ability to search
with `0` or `1` value
    if($switch == 'on') {
        return 1; //all fields with `switch` = 1
    } elseif($switch == 'off') {
        return 0; //all fields with `switch` = 0
    } else {
        return null; //all fields
    }
}
~~~
In this simple way you can teach standard filter fields to search in customized
columns.  

**Another example:**  
The column shows news author name according to their id.
In this situation we must return reverse value. The column returns it in the
following way: `id->author` and customized filter must return
`author->id`. Lets write simple function:

~~~
[php]
public function getAuthor($author)
{
     if(empty($author)) return null; //return al if author is empty
     if(is_numeric($author)) return $author; //return fields if id is entered
     $criteria=new CDbCriteria;
     $criteria->select='author_id'; //select id field
     $criteria->compare('author_login',$author,true); //seach author name.
partialMatch is on
     $am=authorsModel::model()->find($criteria);
     if(empty($am)) return 0; //if author not found - returns 0
     return $am->attributes['adm_id']; //returns author id
}
~~~
That is all!
>Note: This was written simple examples. Situation, when there are several
authors which logins starts from equal letters must return an array with their
IDs.

**Example with several authors starting from equal letters:**  
~~~
[php]
public function getAuthor($author)
     {
         if(empty($author)) return null;
         if(is_numeric($author)) return $author;
         $criteria=new CDbCriteria;
         $criteria->select='author_id';
         $criteria->distinct = true;
         $criteria->compare('author_login',$author,true);
         $am=authorsModel::model()->findAll($criteria);
         if(empty($am)) return 0;
         if(count($am) == 1) return $am[0]->attributes['author_id'];
         $ids = array();
         foreach($am as $a_id)
         {
             $ids[] = $a_id->attributes['author_id'];
         }
         return $ids;
     }
~~~