For each column of the CGridView, we can specify name
, value
, htmlOptions
, cssClassExpression
etc. In the declarations of the attributes value
and cssClassExpression
we can use the "special" variable $data
, for example like this: 'value'=>'$data->author->username',
.
Now we might want to use $data
in the declaration of the htmlOptions
attribute, which is normally not possible, to generate for example the tag <td id="3" class="name_3">
, where 3 is the id of the data model for the current row, i.e. $data->id
. That is, we want to be able to use:
'htmlOptions'=>array('id'=>'$data->id', 'class'=>'"name_{$data->id}"')
Here's a way to accomplish this...
Extend the class CDataColumn ¶
Under protected/components/
create the file DataColumn.php with the following content:
/**
* DataColumn class file.
* Extends {@link CDataColumn}
*/
class DataColumn extends CDataColumn
{
/**
* @var boolean whether the htmlOptions values should be evaluated.
*/
public $evaluateHtmlOptions = false;
/**
* Renders a data cell.
* @param integer $row the row number (zero-based)
* Overrides the method 'renderDataCell()' of the abstract class CGridColumn
*/
public function renderDataCell($row)
{
$data=$this->grid->dataProvider->data[$row];
if($this->evaluateHtmlOptions) {
foreach($this->htmlOptions as $key=>$value) {
$options[$key] = $this->evaluateExpression($value,array('row'=>$row,'data'=>$data));
}
}
else $options=$this->htmlOptions;
if($this->cssClassExpression!==null)
{
$class=$this->evaluateExpression($this->cssClassExpression,array('row'=>$row,'data'=>$data));
if(isset($options['class']))
$options['class'].=' '.$class;
else
$options['class']=$class;
}
echo CHtml::openTag('td',$options);
$this->renderDataCellContent($row,$data);
echo '</td>';
}
}
First note what happens to the cssClassExpression
attribute: if it is set, then it is treated as an expression and is evaluated before further use. During this evaluation, expressions like $data->id
are replaced with their values.
Originally the htmlOptions
attribute is used without any evalution, like this:
$options=$this->htmlOptions;
...
echo CHtml::openTag('td',$options);
What we do differently from the original is:
- We introduce the new boolean variable
$evaluateHtmlOptions
to control whether the evaluation of thehtmlOptions
attribute should be done, or everything should remain as in the original. It defaults to false, so if nothing is given, nothing changes. - We evaluate the
htmlOptions
, if the$evaluateHtmlOptions
is set totrue
.
Use the class CDataColumn ¶
We can use this new class like this:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'article-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'title',
array(
'name'=>'author',
'value'=>'$data->author->username'
),
array(
'class'=>'DataColumn',
'name'=>'sortOrder',
'evaluateHtmlOptions'=>true,
'htmlOptions'=>array('id'=>'"ordering_{$data->id}"'),
),
array(
'class'=>'CButtonColumn',
),
),
));
Where to call this Component?
I jus created the file named DataColumn.php in components and in my grid
'checkBoxColumnConfig' => array( 'class'=>'DataColumn', 'name' => 'id', 'value' => '$data->client_file_id', 'evaluateHtmlOptions'=>true, 'htmlOptions'=>array('id'=>'"ordering_{$data->client_file_id}"'), ),
Error: Property "DataColumn.selectableRows" is not defined.
OH MY GOOOOOD!
Thanks man! I've spent the whole afternoon trying to change the color of rows but htmlOptions wasn't evaluating the string!
You've made my day!
I thing that line....
I thing that line....
$options[$key] = $this->evaluateExpression($value,array('row'=>$row,'data'=>$data));
Should be:
$options[$key] = $this->evaluateExpression($value.$data->id,array('row'=>$row,'data'=>$data));
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.