Cbuttoncolumn - Adding Dynamic Parameters To Button Url

I have 2 database tables, yii_quote & yii_valuation. A quote contains 0:M valuation. The models have been scaffolded accordingly.

When a user is at the


Quote/admin CGridView

, and they click View from the default CButtonColumn, I wish to override the default behaviour of the view button to direct them to


Valuation/Admin?q=:quote_id

Where


:quote_id

is the id of the quote / current row id.

How do I add this dynamic parameter to the URL?

At present, I have:


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

	'id'=>'quote-grid',

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

	'columns'=>array(

                ...

                ... Quote Related Columns ...

                ...

		array(

			'class'=>'CButtonColumn',

                'buttons' => array(

                    'view' => array (

                        'url' => "Yii::app()->controller->createUrl('valuation/admin', q= // SOMETHING HERE //  )",

                    ),

                ),

		),

	),

)); ?>

Any luck Ahmet?

Hi Gerhard…

Yes, problem solved. Solution is quite simple, however there are some complexities which made this actually quite difficult.

Solution


'url' => 'Yii::app()->controller->createUrl("/valuation/admin", array("q"=>$data->primaryKey))',

Step 1: Selecting the button to override

Firstly, you need to tell Yii which button to change the URL for. In my case, I want to change the view button so… the buttonId being view, I put ‘view’ into the array.

If I wanted to override the default behaviour for delete, I would put ‘delete’ into the array.


'buttons' => array(

                    'view' => array ( [STUFF IN HERE] ),

                ),

http://www.yiiframework.com/wiki/106/using-cbuttoncolumn-to-customize-buttons-in-cgridview/

Step 2: Overriding the URL

You can’t just put a createUrl in here. The problem is that the value stored by the ‘url’ key needs to be in string format. Note the speech marks.




'view' => array (  'url' => 'Yii::app()->controller->createUrl("/valuation/admin"' ),



Step 3: Adding Dynamic Parameters to the URL

You can access the data within that particular row of the table via $data. And the primaryKey for that row is stored as $data->primaryKey.

The following code will append the following parameter to the end of the URL assuming primaryKey is 5 ‘?q=5’


array("q"=>$data->primaryKey))

Putting it all together:


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

	'id'=>'quote-grid',

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

	'columns'=>array(

		'id',

        'description',

		'user_id',

		'date_created',

		'date_expired',

		array(

			'class'=>'CButtonColumn',

                'buttons' => array(

                    'view' => array (                    

                        'url' => 'Yii::app()->controller->createUrl("/valuation/admin", array("q"=>$data->primaryKey))',

                    ),

                ),

		),

	),

)); ?>

Problem is that when scaffolding / using things like gridviews, everything is very much hidden away.

Took me hours to find out how to find one line of code example in documentation below:

Using CButtonColumn to customize buttons in CGridView


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

Customising a gridview buttoncolumn parameter should be common practice. I feel really gutted with such a great framework such as Yii in that:

[list=1]

[*]It is not obvious how to do this

[*]No real examples to help us along

[*]I had absolutely no help on forums

[*]Finding out how to do something so simple took hours!

[/list]

Ahmets

Very cool. I also have buttons and widgets where the url sometimes must be a string and sometimes not. Many hours - as you said.

However, I still need to find out how to add a normal parameter (not the gridview id/key) to the url. I have parameter in my view that was received from the controller. I want to send it back to the controller - probably in the url.

Could you try to add the data to your dataprovider, but not display it in the gridview? That way you could use it in your url as a parameter?

Sounds like an option yes.

Or maybe store parameter in hidden field that you extract with jquery.

Thanx.

I got this solved the following way:

  1. Do not pass the value in a normal variable from the controller-action to the view.

  2. Store the value in a public variable in the controller.

  3. In the view - ‘pull’ the public variable into the gridview button’s url (or into a parameter passed to a js function - like I did).

The controller:


/ *  Outside the action */

public $arrayName = null;


/* Inside the action */

$this->arrayName = 'myArray1';

CGridView button in the view:


'buttons'=>array(


	'mydelete'=>array(

		'label'=>'Delete',

		'url'=>'$this->grid->controller->createUrl("delete")',

	

		'click'=>'function(){

			jsFunction(	

				$(this).attr("href"),

				"'.$this->arrayName.'"

			);

			return false;

		}',

	),

),