Yii 1.1: Special $variables in CGridView and CListView

36 followers

The popular CListView and CGridView widgets each take a data provider and iterate over each data object produced, calling the user's code to render each row one at a time, and most are familiar with the use of the $data variable to represent the current model object or array.

But there are additional special variables as well, including those that make their way all the way back to the calling controller, and this page means to reference them all.

CListView

The CListView widget calls your partial rendering _view on each item, setting these variables before calling each one:

  • $data - the current object or hash being rendered
  • $index - the zero-based index of the item being rendered (0, 1, 2, ...)
  • $this - the owner of the widget, usually the calling controller
  • $widget - the CListView widget itself

CGridView

The CGridView widget displays data in tabular form, and when each 'value' => '...' string is eval'd, these variables are available:

  • $data - the current object or hash being rendered
  • $row - the zero-based index of the item being rendered (0, 1, 2, ...)
  • $this - the CGridColumn object representing the column being rendered
  • $this->grid - the CGridView object that owns the column
  • $this->grid->owner - the owner of the grid, usually the calling controller

Passing your own variables

A very common request in the #yii channel is how to pass additional variables to the widget that are available by the rendering code. Though this is straightforward in CListView, it's not so simple in CGridView.

In CListView an additional viewData parameter can be passed to the widget as an array with additional variables:

$this->widget( 'zii.widgets.CListView', array(
    'dataProvider' => $dataProvider,
    'viewData' => array( 'switch' => true, 'blah' => 123 ),    // YOUR OWN VARIABLES
    'itemView' => '_view',
) );

Then, in the _view you can refer to $switch or $blah directly right alongside the other predefined variables.

For CGridView it appears that we have to extend the class to provide the variables in the widget. This extended class might look like:

// components/SpecialGridView.php
Yii::import('zii.widgets.grid.CGridView');
 
class SpecialGridView extends CGridView {
    public $extraparam;
}

and then called in the controller as:

// in your controller
  $this->widget('SpecialGridView', array(
    'dataProvider' => $dataProvider,
    'extraparam'   => 1234          // your special parameter
    'columns' => array( ... ),
  ) );

This done, the extra parameter is available in each the column as $this->grid->extraparam.

Total 11 comments

#18342 report it
Asmaa at 2014/10/19 02:08am
For list

You can access the extraparam in the SpecialCListView using: $widget->extraparam

#16609 report it
hjb at 2014/03/10 09:51am
beware 'zero-based index' statement for CListView

"$index - the zero-based index of the item being rendered (0, 1, 2, ...)"

Turns out this isn't strictly true. It's actually taken from the KEY of the data array you send through to the list. So generally it's 0 based but if you've used an 'index' => 'id' or similar then the $index variable will actually be set to your id column value instead.

If you've done a query because you need a different key for something you are doing prior to generating the CListView then the simplest fix is to run the following just before you pass your data though:

$Models = array_values($Models);
#15513 report it
fsb at 2013/11/17 02:39pm
Item number in a data provider's data set

$row is the zero-based ordinal number of the row in the displayed grid. If you have a pager and want to display the ordinal number of a record within the data provider's dataset:

'value' => '$row + $this->grid->dataProvider->getPagination()->currentPage '
    . '* $this->grid->dataProvider->getPagination()->pageSize'

In the context of a CDataColumn::value’s eval()'d code, the grid’s data provider instance is

php $this->grid->dataProvider

and its pagination instance is

php $this->grid->dataProvider->getPagination()

Writing all this in a string (for eval()) is ugly but it works.

#12540 report it
Karl Zilles at 2013/03/27 06:10pm
If you're on php 5.3, and everyone should be if they can

Then you can use an anonymous function. If $arr is the array you want to access:

array(
'name'=>'column_with_page_variable',
'value'=> function($data) use ($arr) { return $arr[$data]; }
)
#12539 report it
toph at 2013/03/27 05:56pm
Passing array variables into CGridView

@ahmad in order to pass the array you'd have to pass it as a string. You can use var_export() to do this.

$arr=array('a'=>1,'b'=>2,'c'=>3);
var_export($arr); //returns the string "array('a'=>1,'b'=>2,'c'=>3)"
#7525 report it
ahmad jahangir at 2012/03/28 02:58am
Sync an array as viewData variable

How can I pass an array as a variable in viewData that sync to each viewItem?

#7122 report it
rrbot at 2012/02/24 06:38pm
Single Variables

Thanks zilles, good to know. I think my comment could serve as clarification for users who only need a simple variable and not an array. Maybe SJFried could include? Could save users some considerable effort for a single variable.

Any clue why ListView has such a data input by gridview does not? I'd really like to see this addressed in core.

#7121 report it
Karl Zilles at 2012/02/24 06:31pm
RRBot, that's a good trick, but it only works for simple string variables

If you want to dereference an array based on data from the row, for example, it won't work.

#7097 report it
rrbot at 2012/02/23 02:37pm
Pass Variables to CGridView

Extending the Grid view is not required. The below column references $sales which is available to the page, but not the CGridView...

array(
'name'=>'column_with_page_variable',
'value'=>'$cost/'.$sales.' Dollars'
)
#5442 report it
Steve Friedl at 2011/10/12 09:54am
Thanks redguy!

I've updated the article with your helpful information, thank you.

#5405 report it
redguy at 2011/10/10 04:55am
passing additional variables

You can always use 'viewData' param from CListView widget. The you can access every variable passed like this as local variable in rendering view. Example:

$this->widget( 'CSListView', array(
    'dataProvider' => $dataProvider,
    'viewData' => array( 'switch' => true ),
    'itemView' => '_view',
) );

and then you can access 'switch' variable in _view.php like this:

if( $switch ) {
  echo $data->attribute;
}

Leave a comment

Please to leave your comment.

Write new article