2

In an ActiveDataProvider you can use closures as values, like:

$dataprovider = new ArrayDataProvider([
    'allModels' => $array
]);

$gridColumns = [
    'attrib_1',
    [
        'attribute' => 'attrib_2',
        'label' => 'Label_2',
        'value' => function($model) {
            return Html::encode($model->value_2);
        }
    ],
    'attrib_3'
];

echo GridView::widget([
    'dataProvider'=> $dataprovider,
    'columns' => $gridColumns
]);

Is it possible to do the same or something like this, in an ArrayDataProvider?

JK87
  • 379
  • 2
  • 12
  • 26

2 Answers2

2

Yes. Only difference is that $model is not an object but array so:

'value' => function($model) {
    return Html::encode($model['value_2']);
}
Bizley
  • 17,392
  • 5
  • 49
  • 59
  • Thank you. I thought, there is no model, because the dataprovider is based on an self created array. – JK87 Jan 27 '17 at 09:40
1

For this purpose, I have created an extended version of ActiveDataProvider, that for each model got from provider I call a callback.

  1. This is the custom ActiveDataProvider, put in common\components namespace in this case.

    <?php
    
    namespace common\components;
    
    class CustomActiveDataProvider extends \yii\data\ActiveDataProvider
    {
    public $formatModelOutput = null;
    
    public function getModels()
    {
        $inputModels = parent::getModels();
        $outputModels = [];
    
        if($this->formatModelOutput != null)
        {
            for($k=0;$k<count($inputModels);$k++)
            {
                $outputModels[] = call_user_func( $this->formatModelOutput, $k , $inputModels[$k]); 
            }
        }
        else
        {
            $outputModels = $inputModels;           
        }
    
    
        return $outputModels;
    }
    }
    
  2. This is the action in controller that uses it. For reusability, I call a model method instead calling a clousure, but you can call also a clousure.

     public function actionIndex()
     {
          $query = Model::find();
    
     $dataProvider = new \common\components\CustomActiveDataProvider([
         'query' => $query,
         'pagination' => ['pageSize' => null],
         'formatModelOutput' => function($id, $model) {
             return $model->dataModelPerActiveProvider;
         }
     ]);
    
    return $dataProvider;
    }
    
  3. At last, this is the method getDataModelPerActiveProvider in model:

    public function getDataModelPerActiveProvider()
    {
         $this->id = 1;
         // here you can customize other fields
         // OR you can also return a custom array, for example:
         // return ['field1' => 'test', 'field2' => 'foo', 'field3' => $this->id];
         return $this;
    }
    
Fabrizio Caldarelli
  • 2,982
  • 11
  • 14