Search code examples
yiicgridview

How to use rowdata variables in CCheckBoxColumn


I have grid generated with CGridView

'id'=>'grid',
'type'=>'striped bordered condensed',
'selectableRows'=>2,
'dataProvider'=>$data,
'template'=>"{items}",
'rowCssClassExpression'=>'(($data["deleted"])?"deleted":"")',
'ajaxUpdate'=>true,
'columns'=>array(
    array(
        'class'=>'CCheckBoxColumn',
        'checkBoxHtmlOptions'=>array(
            'name'=>'checkbox[id][]',
            'class'=>'grid-checkbox',
            'data-aaa'=>'$data["aaa"]',
            'data-bbb'=>'$data["bbb"]',
        ),
    ),

I can get access to $data variable in rowCssClassExpression. But at the same time in 'checkBoxHtmlOptions' of CCheckBoxColumn $data is parsed as a string:

<input type="checkbox" ... data-aaa="($data["aaa"])" data-bbb="($data["bbb"])">

How can I get access to $data variable?


Solution

  • The framework does not support PHP expressions for htmlOptions array. Expressions are only supported for checked cssClassExpression disabled and value in CCheckBoxColumn See the documentation on properties of CCheckBoxColumn here

    The data for data cell is rendered like this

    public function renderDataCell($row)
    {
        $data=$this->grid->dataProvider->data[$row];
        $options=$this->htmlOptions;
        if($this->cssClassExpression!==null)
        {
            $class=$this->evaluateExpression($this->cssClassExpression,array('row'=>$row,'data'=>$data));
            if(!empty($class))
            {
                if(isset($options['class']))
                    $options['class'].=' '.$class;
                else
                    $options['class']=$class;
            }
        }
        echo CHtml::openTag('td',$options);
        $this->renderDataCellContent($row,$data);
        echo '</td>';
    }
    

    Refer here for the source. As you can see only cssClassExpression is currently using the evaluateExpression function, which evaluates the $data based expression.

    The only solution is extend the CCheckBoxColumn and overwrite the function You can do so by creating a file say MyCheckBoxColumn in your components folder like this

    <?php 
    class MyCheckBoxColumn extend CCheckBoxColumn { 
    
        public $htmlOptionsExpression; 
    
        public function renderDataCell($row)
        {
            $data=$this->grid->dataProvider->data[$row];
            $options=$this->htmlOptions;
            if($this->cssClassExpression!==null)
            {
                $class=$this->evaluateExpression($this->cssClassExpression,array('row'=>$row,'data'=>$data));
                if(!empty($class))
                {
                    if(isset($options['class']))
                        $options['class'].=' '.$class;
                    else
                        $options['class']=$class;
                }
            }
            if($this->htmlOptionsExpression != null){
                 foreach ( $this->htmlOptionsExpression as $attribute => $optionExpression) {
                     $value=$this->evaluateExpression($optionsExpresion,array('row'=>$row,'data'=>$data));
                     $options[$attribute] = $value;
                 }
            }
            echo CHtml::openTag('td',$options);
            $this->renderDataCellContent($row,$data);
            echo '</td>';
        }
    }
    

    and finally use this in your CGridview

    'id'=>'grid',
    'type'=>'striped bordered condensed',
    'selectableRows'=>2,
    'dataProvider'=>$data,
    'template'=>"{items}",
    'rowCssClassExpression'=>'(($data["deleted"])?"deleted":"")',
    'ajaxUpdate'=>true,
    'columns'=>array(
        array(
            'class'=>'MyCheckBoxColumn',
            'checkBoxHtmlOptions'=>array(
                'name'=>'checkbox[id][]',
                'class'=>'grid-checkbox',
            ),
            'htmlOptionsExpression'=>array(
                'data-aaa'=>'$data["aaa"]',
                'data-bbb'=>'$data["bbb"]',
            ),
        ),
     ),