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:
$this->widget('zii.widgets.grid.CGridView', array ( 'id'=>'examinations-grid', 'selectableRows'=>1, 'selectionChanged'=>'function(id){alert($.fn.yiiGridView.getSelection(id))}', ... }
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:
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); }); ");
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:
'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."}}}"' ), ... )
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:
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]; }
That was all. For me this solution work like a charm.