[SOLVED] CButtonColumn to display "some text" instead of "button" according to "$data"

Dear everyone,

I’m trying to set up CButtonColumn with the following requirement.

Let says there is a $data like




[0] => array (

         'submit_date' => '10.01.2011'

       ),

[1] => array (

         'submit_date' => ''

       ),



I want to create a CGridView and use CButtonColumn for

  1. display a button if ‘submit_date’ is empty.

  2. display a text of date if ‘submit_date’ is not empty.

Here is what I’ve tried to do. I create 2 buttons, one for display a button if ‘submit_date’ is empty and another one for ‘submit_date’ is not empty and that the button which I don’t know how to display its as text and without link to anywhere.

Here is a part of my code




$this->widget('zii.widgets.grid.CGridView', array(

		'id'=>'data-grid',

		'dataProvider'=>$model->getData(),

		'columns'=>array(	

			array(

				'class'=>'CButtonColumn',

				'header'=>'Operations',

				'template' => '{date}{submit}',

				'buttons' => array(

					'date' => array(

						'lable' => 'date("F j, Y",strtotime($data[submit_date]))',

						'imageUrl' => '',

						'visible'=>'$data[submit_date]!=""',

					),

					'submit' => array(

						'imageUrl'=>Yii::app()->request->baseUrl.'/images/submit.png',

						'visible'=>'$data[submit_date]==""',

					),

				),

			),								

		),

	));		



It failed to display text instead of button name and the href link still here.

So is it possible to do it? and how?

Thanks in advance.

First, you have a typo in keyword ‘label’.

In CGridView, different column types use different combinations of immediate evaluation (grid level) vs "deferred" evaluation (when rendering a column of a row).

You can customize a CDataColumn for most purposes.

Previously I tried to include an ajax link by extending CButtonColumn. See this thread. (Not a good solution).

For your label usage you can extend CButtonColumn like this (I performed just a quick test, there may be other problems)

protected/components/ButtonColumnEx2.php




<?php

class ButtonColumnEx2 extends CButtonColumn

{

  protected function renderButton($id,$button,$row,$data)

  {

    if (isset($button['label']))

      $button['label'] = $this->evaluateExpression($button['label'],array('data'=>$data,'row'=>$row));


    parent::renderButton($id,$button,$row,$data);

  }

}



Example of usage (variables $row and $data available)




...

'columns'=>array(

  array(

    'class'=>'ButtonColumnEx2',

    'template'=>'{test}',

    'buttons'=>array(

      'test'=>array(

        'label'=>'$row',

      ),

    ),

  ),

),



This extended renderButton() method forces label to be evaluated instead of just using the grid level value supplied. The extended method is kept simple by replacing the supplied value before calling the standard CButtonColumn method.

Edit:

Perhaps this solution can be extended to a more generic ButtonColumnEval class, possibly using some string prefix for enabling evaluation mode.

/Tommy

Thanks it works!

Here is what my extend button column component look like




class ButtonColumnSubstitute extends CButtonColumn

{

	protected function renderButton($id, $button, $row, $data)

	{

		if (empty($button['url'])) {

			if (isset($button['visible']) && !$this->evaluateExpression($button['visible'],array('row'=>$row,'data'=>$data))) {

				return;

			}			

			

			if (isset($button['label'])) {

				echo $this->evaluateExpression($button['label'],array('data'=>$data,'row'=>$row));

			}

		} else {

			parent::renderButton($id,$button,$row,$data);	

		}

	}

}



This is how I called it in CGridView




			array(

				'class'=>'ButtonColumnSubstitute',

				'header'=>'Completed Date',

				'template' => '{date}{submit}',

				'buttons' => array(

					'date' => array(

						'label' => 'date("F j, Y",strtotime($data[submit_date]))',

						'url' => '',

						'visible'=>'$data[submit_date]!=""',

					),

					'submit' => array(

						'label' => 'Submit!',

						'url' => '"some URL"',

						'imageUrl'=>Yii::app()->request->baseUrl.'/images/submit.png',

						'visible'=>'$data[submit_date]==""',

					),

				),

			),



And here is how it works.

  1. 2 buttons are called with 2 visible logic, display submit button when submit_date doesn’t set and display only just a submit date when submit_date presents.

  2. To prevent link when display as submit date. I override button render when url option is set as empty. (This would be a nice feature to have in order to disable link if someone need to do some ajax or other thing without using hyperlink)

Great post, I was looking for it