Radio Button Group bound to data in a CGridView Column

I’ve been trying to specify a CGridView column that would dynamically display (and allow changing of) a value from the recordset. I’ve tried several ways to specify that the radio button list is tied to the data model, but none of them seem to work. Here’s the best column specification I have:


array(

	'header' => 'Timeliness',

	'type' => 'raw',

	'value' => "CHtml::activeRadioButtonList($data,'Lease_Action_id',array('1'=>'OK','2'=>'Late','3'=>'Very Late'),array(

	    'labelOptions'=>array('style'=>'display:inline'), // add this code

	    'separator'=>'',

	))",

),

In the column I get this:

If I put quotes around the $data variable like this:


array(

	'header' => 'Timeliness',

	'type' => 'raw',

	'value' => "CHtml::activeRadioButtonList('$data','Lease_Action_id',array('1'=>'OK','2'=>'Late','3'=>'Very Late'),array(

	    'labelOptions'=>array('style'=>'display:inline'), // add this code

	    'separator'=>'',

	))",

),

(which doesn’t make any sense, but I’m trying anything), I get this, which seems clear enough:

But I thought that specifying $data for parameter 1 would pass an object. When I try specifying the dataprovider object for parameter 1 it does parse it correctly as an object, and it throws a different error:

To me that just says that $data ought to work. Or is that not the right name for the row’s data object?

Can anyone help, please? I’ve searched high and low and haven’t found anything at all about binding either a radiobuttonlist or a dropdownlist to a data value in a gridview. Is it possible?

Thanks.

Try using an anonymous function:




array(

        'header' => 'Timeliness',

        'type' => 'raw',

        'value' => function($data){

                // PHP code here

                // Return the value that you wish to display

        },

),

That should at least make the problem easier to spot, if a problem still exists.

escape variables so they will be parsed at rendering, not at declaration…




'value' => "CHtml::activeRadioButtonList(\$data,'Lease_Action_id',array('1'=>'OK','2'=>'Late','3'=>'Very Late'),array(

            'labelOptions'=>array('style'=>'display:inline'), // add this code

            'separator'=>'',

        ))"



or you can create class for such column:




Yii::import( 'zii.widgets.grid.CDataColumn' );


class CSDropDownColumn extends CDataColumn {


    public $values = array( );


    public function init() {

        parent::init();

        $this->filter = $this->values;

    }


    protected function renderDataCellContent( $row, $data ) {

        echo CHtml::activeDropDownList( $data, $this->name, $this->values );

    }


}



and use it simpler:




array(

        'class'=>'CSDropDownColumn',

        'name' => 'Lease_Action_id',

        'header' => 'Timeliness',

        'values'=>array('1'=>'OK','2'=>'Late','3'=>'Very Late'),

),



I like this. I’m going to make a note of this for future reference.

Thanks a lot for the quick reply. Unfortunately, neither of these solutions seems to work quite right for me. The first one (escaping the $data variable) does eliminate the errors and does give me a radio button group, but each radio button group in a multi-line grid gets the same name, therefore the browser renders the “checked” property correctly only on the last line of the grid. The class-based solution, which you coded for a drop-down list rather than the radio buttons I was trying for, also gives the same name to each selector, but apparently that doesn’t matter to the browser, because the “selected” property does give the correct results in each row. When I adapted your class code for a radio button list, it reverted to the first problem – only the last row’s radio buttons show a selection because they all have the same name.

I solved it by using the first (escaped variable) solution and adding a name attribute to the htmlOptions array where I construct the name by appending a row-unique value. How would you extend your class-based solution to include the htmlOptions array?

simply:




class CSRadioColumn extends CDataColumn {


    public $values = array( );

    public $htmlOptions = array();


    public function init() {

        parent::init();

        $this->filter = $this->values;

    }


    protected function renderDataCellContent( $row, $data ) {

        $options = $this->htmlOptions;

        $options['name'] = $this->name . '[' . $data->primaryKey . ']';

        echo CHtml::activeRadioButtonList( $data, $this->name, $this->values, $options );

    }


}



That is outstanding. Thanks so much for the timely and helpful responses. Much appreciated.