Yii 1.1: CGridView: Use special variable $data in the htmlOptions of a column (i.e. evaluate htmlOptions attribute)

16 followers

    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:

  1. We introduce the new boolean variable $evaluateHtmlOptions to control whether the evaluation of the htmlOptions attribute should be done, or everything should remain as in the original. It defaults to false, so if nothing is given, nothing changes.
  2. We evaluate the htmlOptions, if the $evaluateHtmlOptions is set to true.

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',
        ),
    ),
));

Total 3 comments

#16478 report it
toall at 2014/02/27 04:14am
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));
#14540 report it
migueArgentina at 2013/08/21 07:12pm
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!

#14235 report it
jackhad at 2013/07/29 08:51am
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.

Leave a comment

Please to leave your comment.

Write new article