Yii 1.1: CGridView. Add custom class to table rows preserving original „odd“ and „even“

6 followers

Lets say we have such a CGridView widget showing a list of users for administrator. Users have status „active“ or „disabled“. Grid widget puts class „odd“ or „even“ to rows and we want to preserve this. So we want to add a class „disabled“ to rows with disabled users.

Implementation

<?php
$this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'rowCssClassExpression' => '
        ( $row%2 ? $this->rowCssClass[1] : $this->rowCssClass[0] ) .
        ( $data->status ? null : " disabled" )
    ',
    'columns'=>array(
        'username',
        array(
            'name' => 'status',
            'value' => '$data->status0->title',
        ),
        array(
            'class'=>'CButtonColumn',
            'header' => Yii::t( 'app', 'Tools' ),
        ),
    ),
));
?>

Comments

$model here is a User model pushed to view from controller. $data->status0->title here is User's property from relation to other model (why it is $data and not $model see bellow).

rowCssClassExpression

All „magic“ we do in „rowCssClassExpression“ property. Its value is a PHP expression. Expression is evaluated for every data row. Result of evaluation is used as the CSS class name. Note, that PHP expression is string.

cssClassExpression

We put „rowCssClassExpression“ property to „top“ CGridView properties – thus class will be aplied to row. If we put another „cssClassExpression“ property to some column – we can set a class for single cell. E.g.:

<?php
array(
    'name' => 'status',
    'value' => '$data->status0->title',
    'cssClassExpression' => '"foo" . (2+3) ."bar"',
),
));
?>

as result we will have

<td class="foo5bar">

(note the difference between „rowCssClassExpression“ and „cssClassExpression“) From widget you can access such a variables:

  • $row : the row number (zero-based)
  • $data : the data model for the row
  • $this : the column object. As you can see we use all of them.

Expressions

This

( $row%2 ? $this->rowCssClass[1] : $this->rowCssClass[0] ) .

evaluates to 0,1,0,1... as rows are processed and original „odd“ or „even“ values are returned. CGridView::rowCssClass property is array containing default class values (in means of html element attribute). This property is ignored in widget because of rowCssClassExpression property is used. But values are accessible :) This expressions then is concatenated (note dot at the end) with:

( $data->status ? null : " disabled" )

$data here is User model and „status“ is its property (0 or 1 in this case). You can't access $model variable from those string expressions.

Total 2 comments

#13562 report it
Maug Lee at 2013/06/06 03:25am
And more

Good point to use CHtml::value(). Also count($this->rowCssClass) can be 0 (when there are no predefined class attributtes for row). In this case a „Division by zero“ error will appear ($row % 0). So for original class portion it could be:

count($this->rowCssClass) ? $this->rowCssClass[ $row % count($this->rowCssClass) ] : ""
#13542 report it
le_top at 2013/06/05 04:15am
A bit more general

As there can be more than two classes in rowCssClass, one should write something like this:

'rowCssClassExpression'=>'$this->rowCssClass[$row%count($this->rowCssClass)].(!CHtml::value($data,"entity.is_active")?" invisible-entity":(CHtml::value($data,"entity.device.is_active")?"":" inactive-entity"))',

The rowCssClass array is indexed directly (instead of using an inline test). Futher, the above example may actually add one out of two other classes and introduces the use of CHtml::value which avoids exceptions in case $data->entity or $data->entity->device is null.

Leave a comment

Please to leave your comment.

Write new article