Hello I am quite new to Yii Framework and I am following Larry Ullman's Tutorial Series. I have a Employee model and a Department Model. The Department Model has a has_many relation with Employee Model , departmentId being the foreign key in Employee Model.
In the admin view, I have a search bar followed by a list of Employee, I want to display the name of the Department instead of the departmentId, and also make the search through department name. For a try, I wrote the following code having an array corresponding to departmentId field. This one worked for the view action but is not working for the admin action .
Kindly Help.
<?php
echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
));
?>
</div><!-- search-form -->
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'employee-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
array(
'name'=>'departmentId',
'value'=>$model->department->name,
),
//'departmentId',
'firstName',
'lastName',
'email',
'ext',
/*
'hireDate',
'leaveDate',
*/
array(
'class'=>'CButtonColumn',
),
),
)); ?>
Your view action is just a list view generated from a single model, I'm assuming. This code doesn't work in this case because CGridView is generating each row with data returned from the CActiveDataProvider you're specifying using $model->search()
. So $model
, in this case, is only the current model, and doesn't contain data generated by your query.
To get this to work, value
should be a string that CGridView can evaluate as PHP code. So it should look like this 'value'=>'$data->department->name;',
( $data
is the variable Yii uses to provide the current row to CDataColumn).
The best way I found for creating an extra searchable relation column in a gridview is by using the following pattern:
// the model class
class Product extends CActiveRecord {
// create a custom field in your model class to hold your search data
public $searchSupplierName;
// [...]
// make sure the custom field is safe to set in your rules
public function rules() {
return array(
// [...]
// add your custom field name to this rule
array('id, searchSupplierName', 'safe', 'on'=>'search'),
);
}
// edit your search function
public function search() {
// [...]
// use the value of the custom attribute as a condition in your search
$criteria->compare('supplier.name', $this->searchSupplierName,true);
// you could use something like the following
// to make sure you don't fire a lazy loading query
// for every result that is shown on the gridview.
if($this->searchSupplierName)
$criteria->with = array( 'supplier' );
// then do something like this if you want to be able to sort on the field
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>array(
'attributes'=>array(
'searchSupplierName'=>array(
'asc'=>'supplier.name',
'desc'=>'supplier.name DESC',
),
'*', // this makes sure the rest of the field sorts keep working
),
),
));
}
}
// in the template
<?php
$this->widget('zii.widgets.grid.CGridView', array(
// set the dataprovider to the changed search function output
'dataProvider' => $model->search(),
'filter' => $model, // model is an instance of Product in this case (obviously ;)
// [...]
'columns' => array(
// [...]
// this is the column we care (extra) about
// notice I still use a custom value here (as @ethan describes in his answer)
array(
'name' => 'searchSupplierName',
'value' => '$data->supplier->name',
),
),
));
?>
This solution should work for (almost) any case you want. It is the best solution I can think of if you want text based filtering on the column.
But there are other options as well. For example if you just want to search on a relation_id
by using a combobox to find the right value there are less complicated solutions .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.