How To Access Variable Passed From Controller Into Cgridview

I have a Controller with action. In the action I render a view and pass an array to the view such as:




$this->render('view', array(

                        'hours'                 =>      $object->hours,

            ));



hours is an array of the type array(‘Name’=>200)

What I am trying to achieve is in the view I am rendering CGridView and in one of the columns I would like to display the hours to the respective name. Now in the CGridView I have a column which displays the name and another which should display the hours. How can I inject the array which was passed from the controller so I can display a value of the respective name.

Here is the columns section which I am struggling with:




array('name'=>'team', 'type'=>'raw', 'header'=>'Team'),

array('name'=>'hours', 'header'=>'Hours', 'value'=>............),



Cheers.

Dear Friend

We can do it in the following way.




array('name'=>'hours',

      'header'=>'Hours', 

      'value'=>function($data,$row) use($hours)

                      {

                        return isset($hours[$data->name])?$hours[$data->name]:'';

                      }


),



Regards.

Thank for your reply seenivasan. I should’ve mentioned that the project is running on PHP 5.1 hence anonymous functions are not supported. Any other ides?

Can you not do the same thing but use a callback function rather than an anonymous function?

It would not be the same. The thing is that I am generating this array with a heavy query. So what I am trying to prevent is call that query for every row generated by CGridView so I am trying to pass all the data via controller and then reuse it in the form of an array but I cannot seem to find a way to inject that array into CGridView which is a pain in the but :P

It’s not an elegant solution, but you can declare some property (public variable) in the controller to hold your data.

Then it can be accessed from the CDataColumn’s value expression.




'$this->grid->controller->hours'



Where $this is a CDataColumn. It has a property ‘grid’ that means the parent grid. And the CGridView has a property ‘controller’. And then … :D

inspired by @softark, do this:

  1. in model, add virtual property

public $myhour;

  1. in control, pass array to view

$this->render('list', array(

	'model' => $model,

	'hours' => $hours,

));



  1. in view,

'dataProvider' => $model->search($hours), //<--pass $hours to model search function!

//~~

'columns' => array(

//~~

array(

	'name'=>'myhour',

	'value'=>'$data->myhour',

),

//~~



  1. back to model search function, ta-ta!

public function search($hours = null) {


//~~

	

$dataProvider = new CActiveDataProvider($this, array(

	'criteria' => $criteria,

));


//~~ trick here !!!

if ($hours){

	foreach($dataProvider->data as $one)

	{

		if (isset($hours[$one->name]))

			$one->myhour = $hours[$one->name];

	}

}


return $dataProvider;


}