Yii2: Pass columns to Gridview

Hello…

I need to build the Gridview columns dynamically depending on what my customer is measuring. For example: One customer may have columns "quality", "speed", "satisfaction" and another customer may have "quality", "rank", "success"

As a result, I want to dynamically build my Gridview columns array as follows:

Controller:


        $columns = [];

        foreach ($departments as $department) {

            $columns[] = [

                'attribute' => '"'.$department->name_abbr.'"',

                'label' => '"'.$department->name_abbr.'"',

                'value' => '"'. MetricDepartment::getDepartmentScore($department->id).'"',

            ];

        }

View:


    <?= GridView::widget([

        'dataProvider' => $dataProvider,

        'filterModel' => $searchModel,

        'columns' => $columns,]); 

    ?>

But this causes the grid to lookup the value within the model, resulting in an error.

For example: ‘value’ => “high”

results in an error: Getting unknown property "high"

Is there a way to pass "high" to the value as a fixed value, not as a property?

Many thanks

This seems to work




//...

$columns[] = [

  //...

  [

    'label' => 'header',

    'value' => function () { return 'string literal'; },

    //...  

    //... or

    'content' => function () { return 'str literal'; },

  ],

  //...

],

//...



Reference

Example from Yii Guide

It only works if you use that code within the view. My understanding of Yii is that we should really avoid doing that and, instead, should pass things from the controller.

However, if you use the same code within the controller the function becomes "live" and tries to execute within the controller. If you wrap it in inverted commas then it is seen as text and the view tries to find a matching function within the model.

Should I simply put this code within the view?

For anybody else trying this, here is the solution I found:

Controller:

Get a list of departments (or whatever you want)

View:

Loop through the list and populate the columns:


   <?php

 $deptColumns = []; 

    foreach ($departments as $department) {%20one%20column%20for%20each%20department

        $deptColumns[] = [

            'attribute' => $department->name_abbr,

            'label'=>$department->name_abbr,

            'content' => function($model) use ($department){

                return Whatever-you-need-goes-here; 

            },

        ];

    }

And now you can add this to Gridview:


    <?= GridView::widget([

        'dataProvider' => $dataProvider,

        'filterModel' => $searchModel,

        'columns' => $columns,]);

    ?>