Custom Parameters In Cgridview Button Url (Solved)

Hi

I display a session-array in a gridview using CarrayDataProvider. So I can’t use “normal” statements/functions to get the value of the id column.

In my gridview, I have this button with a customised url.




'buttons'=>array(

	'remove'=>array(

		'label'=>'Remove',


		'url'=>'$this->grid->controller->createUrl("remove", array(

			"idVal"	=> "jquery statement to get gridview column value",

			"parVal"=> "$parameter_received_from_the_controller",

		))',

		

		'click'=>'function(){

			confirm_delete(

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

				"Are you sure you want to REMOVE this record?"

			);

			return false;

		}',

	),

),



I have a few questions:

  1. How do I use js/jquery to extract the data of a column to put in idVal?

  2. How do I return a parameter to the controller in parVal (the parameter was first passed by the controller to the view )?

  3. When do you include the entire url-generating-code in quotes (‘url’=>’$this…’ ) and when not (‘url’=> $this…)?

  4. With javascript in your buttons, when do you use ’ ', " ", or nothing and js: ?

Thanx

Hi,

First of all, without even deep looking at your code, you have to many single and double quotes at one place, so your code simply can’t work! :]

First thing I would do, would be such change:


$jsIdValueCode = "js: $(this).parent().parent().children(':nth-child(1)').text()";


'buttons'=>array(

    	'remove'=>array(

            	'label'=>'Remove',

               

            	'url'=>'$this->grid->controller->createUrl("remove", array(

                    	"idValue"   	=>  	'.$jsIdValueCode.',

                    	"arrayName" 	=>  	"$variable_passed_from_controller",

            	))',

               

            	'click'=>'function(){

                    	confirm_delete(

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

                            	"#edit1Div",

                            	"Are you sure you want to DELETE this record?"

                    	);

                    	return false;

            	}',

    	),

),

to make your code at least compilable, i.e. not generating syntax errors.

Second of all, even after above change, it won’t work! :] You’re mixing two completely different approaches. You’re trying to force Yii (server-side) to generate URL for you, and you’re trying to feed it (one of parameters) with jQuery code, which is executed at client side.

In other words, following line:


'url'=>'$this->grid->controller->createUrl("remove", array(

                    	"idValue"   	=>  	"js: $(this).parent().parent().children(':nth-child(1)').text()",

                    	"arrayName" 	=>  	"$variable_passed_from_controller",

            	))',

is a complete madness! :] I don’t think, you would make this working, even if you would stand on your own head! :]

Look at CButtonColumn.buttons in the documentation. It is said there clearly, that you can use PHP expression (server-side, Yii code) only for url and visible and for nothing else. In the same time, you can use Javascript expression (client-side, jQuery code) only for click and for nothing else. You, most certainly, can’t mix jQuery and PHP in one place.

I’m doing similar magic in my project, like you would like to do, but I’m using a completely different approach. I have copied original CButtonColumn.button.click code from Yii source and modified it to my own needs. Here is an example.

My entire CButtonColumn is generated via this function:


	public static function getStandardButtonColumn($grid, $deleteText)

	{

    	return array

    	(

        	'class'=>'bootstrap.widgets.TbButtonColumn',

        	'header'=>'Operations',

        	'template'=>'{update}{delete}{view}',

        	'htmlOptions'=>array('style'=>'width: 70px'),

        	'buttons'=>array

        	(

            	'view'=>self::getStandardButton($grid, 'Podgląd'),

            	'update'=>self::getStandardButton($grid, 'Edycja'),

            	'delete'=>self::getStandardButton($grid, 'Usunięcie', TRUE, $deleteText)

        	)

    	);

	}

It is called as a part of CGridView.columns array, generates array for entire CButtonColumn, and adds it for arrays that defines other

It does nothing else except defining some standard CButtonColumn properties.


	public static function getStandardButton($grid, $title, $isDeleteButton = FALSE, $deleteText = '')

	{

    	$buttonArray = array

    	(

        	'options'=>array

        	(

            	'title'=>$title,

            	'style'=>'text-decoration: none; padding-right: 3px',

            	'data-delay'=>CJavaScript::jsonEncode(array('show'=>500, 'hide'=>0))

        	)

    	);

       

    	if($isDeleteButton)

    	{

        	if(Yii::app()->request->enableCsrfValidation)

        	{

            	$csrfTokenName = Yii::app()->request->csrfTokenName;

            	$csrfToken = Yii::app()->request->csrfToken;

               

            	$csrf = "\n\t\t\t\tdata:{ '$csrfTokenName':'$csrfToken' },";

        	}

        	else $csrf = '';


        	$buttonArray['click'] =

        	"

            	function()

            	{

                	var

                    	url = $(this).attr('href'),

                    	title = $(this).closest('tr').find('td').html(),

                    	question = '".$deleteText." <br /><br /><small>This operation <strong>can not be undone</strong>!</small>';

                           

                    	question = question.replace(/{title}/g, title);

                   

                	apprise(question, {'verify':true, 'textYes':'Kontynuuj', 'textNo':'Anuluj'}, function(r)

                	{

                    	if(r)

                    	{

                        	jQuery('#".$grid."').yiiGridView('update',

                        	{

                            	type: 'POST',

                            	url: url,

                            	".$csrf."

                            	success: function(data){jQuery('#".$grid."').yiiGridView('update')}

                        	});

                    	}

                	});

                   

                	return false;

            	}

        	";

    	}

       

    	return $buttonArray;

	}

This function generates every standard button – view, update and delete – and in case of delete button, it replaces its click with my own jQuery function.

This works, like a charm, I have full control on what happens, when user click delete button, and I even managed to replace dully "alerts()" with cool messages library (apprise).

Notice, that I’m using standard urls for standard buttons, so my function does not generate own value for url element of each button. It lets Yii do it itself. If you’re using specialised URLs for these operations, you will have to extend getStandardButton() function, so it will also add ‘url’ key to returned array.

As for your questions:

  1. You have example above. It is more complicated to answer in 1-2 lines. Test my example, read docs, look for Yii source code and you’ll find it.

  2. If this variable is passed from controller to view, then it is accessible in a view like any other variable. Just change:


"parVal"=> "$parameter_received_from_the_controller"

to:


"parVal"=> '.$parameter_received_from_the_controller.'

to inject value of a variable to an array you build for your button (CButtonColumn).

  1. You have these options / possiblities:

a] If you enter it in single or double quotes, they’ll become a string, that will be treaten by Yii as PHP expression to be parsed, so Yii will pass it to “eval()” PHP function, and will return its result as value to this array item. If you make a mistake in PHP expression, the whole script will fail. Keep in mind, that Yii parses string as PHP expression only for certain fields / array’s keys. If you put it into one, that is not parsed by Yii, ti will remain just as any other string and will not be changed to anything.

b] If you enter it without single or double quotes, but with dots, just like in example above (point two), that will mean, that you want to merge results of such function call with rest of your array, just as you would merge single variable with it (point two above).

c] If you enter it without single or double quotes and without dots, the entire script will fail, because this is a syntax error and PHP can’t parse it.

I don’t understand, why you’re using “$this->grid->controller->createUrl”. In this context (view), $this represents controller, so if you want to call createUrl from the controller, you just have to call “$this->createUrl”. Note, that “createUrl” is also part of CWebApplication object, so you can call it static way – “Yii::app()->createUrl” – without using controller, and object-oriented ($this) context).

If your example, both a] and b] should work, because – if I’m not mistaken – $this->createUrl is available both directly to view (using without quotes – point b] and to parsable Yii string (using with quotes – point a].

But, if you would like to use here a special variables, that Yii prepares for you ($row and $data), you have to use it in double quotes, because these variables are available only during Yii parse via eval() function and are (in most cases) undefined directly in a view context.

Look for the documentation of CButtonColumn.buttons property for more details. It says: “In the PHP expression for the ‘url’ option and/or ‘visible’ option, the variable $row refers to the current row number (zero-based), and $data refers to the data model for the row.”

  1. When do you use ’ ’ or " ", it depends on how do you merge your array or string with variables or function call. As for “js:” you use it always, if following string contains any Javascript function or expression, to instruct Yii, that it has to post-process this string with additional commands, to make it Javascript-compatibile, when injecting this view to entire page.

After reading your post and your question, it is clearly seen, that you have strong lack and missings in very basic concepts of PHP programming. You are mixing single and double quotes and you don’t know contextes, when you should or shouldn’t use them. This is fundamental PHP knowledge and it will be very hard for you to code in Yii, until you don’t fill that gaps and don’t get that knowledge. Look for any PHP book or course and read entire part about strings and how to merge them with other strings, variables, arrays, function calls etc.

Thanx a lot Trejder.

Maybe i should be more clear about what I meant with ’ ’ or " " or nothing. Some url (CGridView button) are placed in quotes as a string, while others (dropdownlist - ajax) are not placed in quotes and look like normal yii statements. When do you use which?

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;

		}',

	),

),