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
- theCListView
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
.
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; }
Thanks redguy!
I've updated the article with your helpful information, thank you.
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' )
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.
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.
Sync an array as viewData variable
How can I pass an array as a variable in viewData that sync to each viewItem?
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)"
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]; } )
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
’seval()
'd code, the grid’s data provider instance is$this->grid->dataProvider
and its pagination instance is
$this->grid->dataProvider->getPagination()
Writing all this in a string (for
eval()
) is ugly but it works.beware 'zero-based index' statement for CListView
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:
For list
You can access the extraparam in the SpecialCListView using: $widget->extraparam
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.