Yii 1.1: CButtonColumn: Use special variable $data for the 'id' in the 'options' of a button

8 followers

The problem

In an application I had a CGridView with a CButtonColumn and for an Ajax-Request I needed to make sure that the IDs of the buttons would not change when the GridView was updated so in effect I wanted to link them to the $data->id. So I tried:

array(  'class'=>'CButtonColumn',
    'template'=>'{myButton}',
    'buttons'=>array(
        'myButton'=>array(
            'label'=>'My Button',
            'url'=>'Yii::app()->createUrl("site/doStuff", array("id"=>$data->id))',
            'options'=>array(
                'id'=>'\'button_for_id_\'.$data->id',
            ),
        ),
    ),
),

Which did not work as the 'id' is simply not evaluated using CButtonColumn.

The solution

I found this article which does a similar thing for a normal CDataColumn: CGridView: Use special variable $data in the htmlOptions of a column (i.e. evaluate htmlOptions attribute)

Inspired by it I extended the CButtonColumn class like this:

/**
 * ButtonColumn class file.
 * Extends {@link CButtonColumn}
 * 
 * Allows additional evaluation of ID in options.
 * 
 * @version $Id$
 * 
 */
class ButtonColumn extends CButtonColumn
{
    /**
     * @var boolean whether the ID in the button options should be evaluated.
     */
    public $evaluateID = false;
 
    /**
     * Renders the button cell content.
     * This method renders the view, update and delete buttons in the data cell.
     * Overrides the method 'renderDataCellContent()' of the class CButtonColumn
     * @param integer $row the row number (zero-based)
     * @param mixed $data the data associated with the row
     */
    public function renderDataCellContent($row, $data)
    {
        $tr=array();
        ob_start();
        foreach($this->buttons as $id=>$button)
        {
            if($this->evaluateID and isset($button['options']['id'])) 
            {
                $button['options']['id'] = $this->evaluateExpression($button['options']['id'], array('row'=>$row,'data'=>$data));
            }
 
            $this->renderButton($id,$button,$row,$data);
            $tr['{'.$id.'}']=ob_get_contents();
            ob_clean();
        }
        ob_end_clean();
        echo strtr($this->template,$tr);
    }
}

Basically I'm first checking if the ID should be evaluated which is indicated by a new boolean variable $evaluateID and whether the ID is actually set. Then we try to evaluate it and replace the original with the result which later on gets placed into the HTML-tag.

I can now use this class instead, set the $evaluateID to true and my button IDs will be evaluated correctly. This is how the button gets used now:

array(  'class'=>'ButtonColumn',
    'template'=>'{myButton}',
    'evaluateID'=>true,
    'buttons'=>array(
        'myButton'=>array(
            'label'=>'My Button',
            'url'=>'Yii::app()->createUrl("site/doStuff", array("id"=>$data->id))',
            'options'=>array(
                'id'=>'\'button_for_id_\'.$data->id',
            ),
        ),
    ),
),

The resulting HTML then looks like this:

<td>
    <a id="button_for_id_4711" href="/MyApp/index.php?r=site/doStuff&id=4711"></a>
</td>

Total 5 comments

#13255 report it
gobinath at 2013/05/18 06:52am
How to get the url id??

'url'=>'Yii::app()->createUrl("site/doStuff", array("id"=>$data->id))',

i need this URL id

array( 'class'=>'ButtonColumn', 'template'=>'{myButton}', 'evaluateID'=>true, 'buttons'=>array( 'myButton'=>array( 'label'=>'My Button', 'url'=>'Yii::app()->createUrl("site/doStuff", array("id"=>$data->id))', 'options'=>array( 'onclick'=>'alert(this.url)',//it's not working how to the url id please suggest me

            'id'=>'\'button_for_id_\'.$data->id',
        ),
    ),
),

),

#12443 report it
Dũng Ninh Bình at 2013/03/20 11:09pm
Re: This is not working.

@james.castro1989 When I try to check the link's id, it is just

'button_for_id_'.$data->id

I think you miss line:

'evaluateID'=>true,

It's working fine. Thanks to bluezed.

#11274 report it
james.castro1989 at 2013/01/02 11:10pm
This is not working.

When I try to check the link's id, it is just

'button_for_id_'.$data->id
#10948 report it
bluezed at 2012/12/06 01:43am
Re: Get another value from the data

Hi,

if you want the $data->name value to appear in the id-tag as well you can just add it in like this:

'options'=>array(
                'id'=>'\'button_for_id_\'.$data->id.\'_with_name_\'.$data->name',
            ),

That would give you:

<td>
    <a id="button_for_id_4711_with_name_SomeName" href="/MyApp/index.php?r=site/doStuff&id=4711"></a>
</td>
#10944 report it
musang at 2012/12/05 05:29pm
Get another value from the data

Hello, nice article

I have a question, I've tried to find out but still can't get it. How can I get another value from $data, let's say the $data have 2 variables, 'id', and 'name'. How can I get $data->name ? So I can print it in the html tag

Thank you, Adhi

Leave a comment

Please to leave your comment.

Write new article