Getting values from clicked CGridView row

The task in this post is quite simple. Obtain ID (keyField) of a record holding data for clicked CGridView row and one or more values from it’s columns. If you can/want use jQuery, this isn’t to hard job.

For first part (get ID of a record binded to clicked CGridView row) it all means to use internal jQuery function ($.fn.yiiGridView.getSelection(id)) that Yii Framework Dev Team prepared specifically for this task:

[code language=”javascript”]
$this->widget(‘zii.widgets.grid.CGridView’, array
(
‘id’=>’examinations-grid’,
‘selectableRows’=>1,
‘selectionChanged’=>’function(id){alert($.fn.yiiGridView.getSelection(id))}’,

}
[/code]

Don’t forget to set also selectableRows to 1.

For second part (getting value of particular column), which can be useful, for example for displaying delete confirmation, we’re also use jQuery in a slightly magical way.

In my example, I want to display username and login of a user that is going to be deleted. For this purpose I’ve added a CButtonColumn to my CGridView, with delete button’s class set to “delete-button-that-requires-confirmation”. Of course, I had to use class, not ID, because there can be more than one delete button.

Then for each button having above class I’ve attached click event:

[code language=”javascript”]
Yii::app()->clientScript->registerScript(‘admin-users-delete-confirmation’,
"
$(‘.delete-button-that-requires-confirmation’).click(function()
{
var login = $(this).parent().parent().children(‘:nth-child(1)’).text();
var name = $(this).parent().parent().children(‘:nth-child(2)’).text();
var question = ‘User "’ + name + ‘" (‘ + login + ‘) will be deleted! Continue?’;

return confirm(question);
});
");
[/code]

That would be all for jQuery way. But, if you can’t or don’t want to (bad idea) use jQuery, then this task becomes a quite adventure! I wasn’t able to find ready solution, so I crafted my own. But I had to use a little bit trick. I don’t know, if this is perfect, but for me, it works like a charm.

First, I’ve added two new columns (in the beginning) to my CGridView.columns, filled them with data I need and set them to be invisible:

[code language=”javascript”]
‘columns’=>array
(
array
(
‘type’=>’raw’,
‘headerHtmlOptions’=>array(‘style’=>’display: none;’),
‘htmlOptions’=>array(‘style’=>’display: none;’),
‘value’=>’"{{{".$data->ID."}}}"’
),
array
(
‘type’=>’raw’,
‘headerHtmlOptions’=>array(‘style’=>’display: none;’),
‘htmlOptions’=>array(‘style’=>’display: none;’),
‘value’=>’"{{{".$data->PATIENT."}}}"’
),

)
[/code]

Invisible for end-user, but not for JS script! :] Notice, that these columns are of raw type and their contents are surrounded by {{{ and }}}.

Then I modified my onclick handler attached to every row of that CGridView, so it would extract any value surround by those {{{ and }}} and return it to a proper field:

[code language=”javascript”]
function onGridViewSelectionChange()
{
var inner = this.innerHTML;
var pattern = /{{{.*?}}}/gi;
var matches = inner.match(pattern);
matches = matches.toString().replace(/{{{/gi, "").replace(/}}}/gi, "").split(",");

document.getElementById("pacjent-id").value = matches[0];
document.getElementById("pacjent-name").value = matches[1];
}
[/code]

That was all. For me this solution work like a charm.

Leave a Reply