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
$evaluateHtmlOptionsto control whether the evaluation of thehtmlOptionsattribute 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$evaluateHtmlOptionsis 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.