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:
[html]
<td>
<a id="button_for_id_4711" href="/MyApp/index.php?r=site/doStuff&id=4711"></a>
</td>
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
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>
This is not working.
When I try to check the link's id, it is just
'button_for_id_'.$data->id
Re: This is not working.
'button_for_id_'.$data->id
I think you miss line:
'evaluateID'=>true,
It's working fine.
Thanks to bluezed.
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', ), ), ),
),
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.