How to make some columns not trigger row selection in CGridView

Hi,

Recently I have been trying to modify the CGridView to act as a form for tabular input. Since CGridView doesn’t support input components I decided to make my own column types to support select lists and text fields. This was all fine but when I added


'selectableRows' => 2

to the grid view a problem appeared.

Everytime I clicked the text field or select box to change the selection or to change the test the selection of the row was triggered. This was very annoying and caused serious usability issues. I was looking around for a hook in the grid view for changing this behaviour but there is nothing like a a way of telling a column if it shall be a part of the selection area for the row(not that I could find anyway).

In the CGridView the code for setting up the selectable area looks like this in the Javascript file jquery.yiigridview.js:




if (settings.selectableRows > 0) {

  selectCheckedRows(this.id);

  $(document).on('click', '#' + id + ' .' + settings.tableClass + ' > tbody > tr', function (e) {

    var $currentGrid, $row, isRowSelected, $checks,

    $target = $(e.target);

    if ($target.closest('td').hasClass('button-column') || (e.target.type === 'checkbox' && !$target.hasClass('select-on-check'))) {

    return;

}




As you can see this problem has already been addressed for the button-column feature. So by adding the class button-column to my new columns I got get rid of the problem like this.




array(

  'name'=>'pricingAction',

  'class'=>'SelectBoxColumn',

  'htmlOptions'=>array('class'=>'button-column'),

  'columnContent' => array('submit_change'=>'Submit','reject_change'=>'Reject'),

),



This is quite a dirty hack and can easily cause other problems but for now it does the trick.

If not I would like to suggest to add a new property called something like $excludeFromSelectionArea to the Grid view columns. This way this could be specified when adding the columns to the grid.

Something like this:




array(

  'name'=>'pricingAction',

  'class'=>'TextBoxColumn',

  'excludeFromSelectionArea' => true,

),



Does anybody in the community know of a better way of doing this?

Do you really need the multiple selection or any selection at all?

As this is a tabular input… what does the selection do ?

Good question. I have attached a screenshot to make it easier to understand.

Here is the whole scenario:

  1. I get the suggested pricing data from a web service and fill up the the grid view with the rows.

  2. Now I can change the suggested product price for each row if needed.

  3. Now you can decide if you want to reject or submit the rows using the selectbox.

  4. The check box indicates if the row is going to actually have the data set in the backend on submit.

  5. The submit button for the tabular form submits the data to the server side and the rows with a tick will have their pricing action (Submit/Reject) performed the rest will be ignored. this is quite a lengthy process and should be done with one submit action only(That is not separate reject and submit buttons at the bottom of the form).

  6. We load the report again and the table renders. This time only the rows that did not have a tick next to them show up. This is so that we can hold the suggested price changes to decide if we want to approve or reject it later.

The tick boxes are very handy if the list has e.g. 50 rows and we only want to approve the price change for one line. Then you can easily untick all the rows and only select the one row that you want.

I hope this made it a bit easier to understand.

Thanks

By reading the step 3 and 4 I think you are mixing selecting and checking…

As explained above you just need to disable selecting on the grid and enable selecting(checking) on the checkbox column - check this description - http://www.yiiframework.com/doc/api/1.1/CCheckBoxColumn#selectableRows-detail

1 Like

Ah now I see. It was a bit confusing that the attribute is called selectableRows both on widget level and on the individual check box.

This configuration gives me exactly what I want. You were right I didn’t need the selection option but I got confused since the selectableRows feature on the grid view level was actually ticking the check box on click.




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

     'id'=>'PricingReportProducts',

     'dataProvider'=>$dataProvider,

     'columns'=>array(

       array(

       	'id'=>'ticked_for_pricing_action',

       	'class'=>'CCheckBoxColumn',

        'selectableRows' => 2,

       ),

       array(

           'name'=>'pricingAction',

           'class'=>'SelectBoxColumn',

           'columnContent' => array('submit_change'=>'Submit','reject_change'=>'Reject'),

       ),

       'productId',

       array(

           'name'=>'productPrice',

           'class'=>'TextFieldColumn'

       ))

));

Thanks for your help I am sure this thread will help someone else trying to achieve the same thing as me.

I have now taken away the css hack and it all works great.

Great you solved it… yes the name can be a bit misleading… it’s like that because we had to keep BC at the time the CCheckBox::selectableRows was introduced…

It’s great you solved your issue, I’m sure it will help others too…

This helped me a lot…

Thanks for sharing how you solved it.

:)

Thank you! It’s helped me too. (y)