no $data object with CSqlDataProvider or CArrayDataProvider

From what I can tell, it appears that the $data object is not being populated in CGridViews for use in CGridColumns when the data provider for the CGridView is a CArrayDataProvider or CSqlDataProvider. To test, I made a simple example where I attempt to use the $data object in the cssClassExpression property of a CGridColumn.

My CGridView code is:




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

	'dataProvider'=>$dataProvider,

	'columns'=>array(

		array(

			'name'=>'year',

			'cssClassExpression'=>'($data->year >= 2000)?\'current\':\'old\'',

		),

	),

));



I attempted to use three different data providers, all containing the same structure and data, like so:




// attempt 1

$dataProvider = new CActiveDataProvider('Vehicle');


// attempt 2

$dataProvider = new CSqlDataProvider('SELECT id, year FROM vehicle');


// attempt 3

$dataProvider = new CArrayDataProvider(array(array('id'=>1,'year'=>'1998'),array('id'=>2,'year'=>'1999')));



When I used the CActiveDataProvider the view rendered successfully and the expected class had been set on the table cell. However, when I tried with either the CArrayDataProvider or the CSqlDataProvider I get the error: "Error 500 Trying to get property of non-object".

Is this a bug, or is the $data object not supposed to be available when using CDataProviders other than the CActiveDataProvider? If this is the intended functionality, is there any way around this? I definitely need to be able to access the values from the current "row" for dynamic manipulation/styling of some data. Thanks!

Edit and Clarification: This applies to Yii 1.1.4.

After not getting any comments or replies on this issue, I finally posted it as a bug on the issue tracker. Qiang marked the bug as invalid with the response: "If you use array or sql provider, $data would be an array, instead of an object."

Ah! That makes sense! Too bad that wasn’t mentioned (or I didn’t figure it out) until after I had posted the bug. I tested it out and it worked like a charm. The new CGridView example would look like this:




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

        'dataProvider'=>$dataProvider,

        'columns'=>array(

                array(

                        'name'=>'year',

                        'cssClassExpression'=>'($data["year"] >= 2000)?\'current\':\'old\'',

                ),

        ),

));



Thanks, Qiang!

I have added a comment documenting the above to the CGridView reference page. There is an example there of how to code the buttons.

I can’t see the diference to the code you posted above, can you explain the difference please and would appreciate if you could post a link to your comment.

Anyway i appreciate ANYHELP that shows me how to use CArrayDataprovider instead of CActiveDataProvider.

The difference is in how the $data variable is used within the CGridView instance (in the ‘cssClassExpression’ index of the columns array in this example). In the case where the dataProvider is a CActiveDataProvider, the $data variable is an object, and so members of that object are referenced with -> object notation, like $data->member. In the case where the dataProvider is a CArrayDataProvider or CSqlDataProvider, the $data variable is an array, so “members”, or indices, of the array are accessed with bracket notation, like $data[“member”]. Take a second look at the cssClassExpression index of the columns array in my two examples to see this in action.

Mike (UK)'s comment is at the bottom of the documentation page for CGridView, here: http://www.yiiframework.com/doc/api/1.1/CGridView#c3.

Hope that helps. Good luck!

Excellent! works for me! thanks Luoshiben =)