gridviewyii2dataprovider

Yii2 Display Dynamic GridView inside Accordion Widget


I'm new to Yii2 and I am stuck on a fairly trivial task.

I have two tables/models (Entity and Property). An Entity can have multiple properties but a Property can have only one Entity. These relationships have been defined in the respective models

I am trying to create a Dashboard view for the logged in User that displays the Entities the user is associated with (via a junction table Entityuser). In the view I want an accordion displayed for each Entity and when expanded will display a GridView of the Properties belonging to that Entity. The problem I am having is that GridView is only displaying the last Property model in array returned by the ArrayDataProvider regardless of the entity relationship (i.e. it is also displaying the same Property model in the accordion for all entities).

I have copied my code below. Any assistance would be greatly appreciated. I have spent way too much time on this 😊

Models:

Entity

public function getProperty()
{
    return $this->hasMany(Property::className(), ['entity_id' => 'entity_id']);
}

Property

public function getEntity()
{
    return $this->hasOne(Entity::className(), ['entity_id' => 'entity_id']);
}

Controller:

public function actionDashboard($id)
{
    $model = User::findOne($id);

    $entities = new ActiveDataProvider([
            'query' => Entity::find()
                        ->joinWith('entityUsers')
                        ->where(['entity_user.user_id' => $id]),
            'pagination' => [
            'pageSize' => 10,
        ],
    ]);


  foreach($entities->models as $ent){

  $en_id = $ent->entity_id;

  $dataProvider = new ArrayDataProvider([
       'models' => Property::find()->where(['entity_id' => $en_id])->all(),
       // 'models' => $searchModel->entity_id,
        'pagination' => [
            'pageSize' => 10,
        ],
    ]);
   }        

    return $this->render('userProfile', [
    
    'model' => $model,
    'entities' => $entities,
    'dataProvider' => $dataProvider,

View:

foreach($entities->models as $model){

$entity_id = $model->entity_id;
   
echo Accordion::widget([
    'items' => [
    ['header' => $model->entity,
    'content' => 
                 
   GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
    ['class' => 'yii\grid\SerialColumn'],
    'name',
    'address',
    'city',
    'entity_id',
    'land',
     ['class' => 'yii\grid\ActionColumn',
     'header' => '',
     'template' => '{view}',
     'controller' => 'property',
     'contentOptions' => ['style' => 'width:50px; white-space: normal;'],
    ]]
    ])
    ]
    ],
    'clientOptions' => ['collapsible' => true, 'active' => false]
    
    ]); 
     
    }
   }

Solution

  • You were making $dataProvder for last record only.

    Controller

    foreach ($entities->models as $ent) {
        $en_id = $ent->entity_id;
        $dataProviders[$en_id] = new ArrayDataProvider([
           'models' => Property::find()->where(['entity_id' => $en_id])->all(),
           'pagination' => [
               'pageSize' => 10,
            ],
        ]);
    }
    return $this->render('userProfile', [
        'model' => $model,
        'entities' => $entities,
        'dataProviders' => $dataProviders,
    ]);
    

    View

    foreach($entities->models as $model){
       $entity_id = $model->entity_id;
       $dataProvider = $dataProviders[$entity_id];
    
       echo Accordion::widget([
        .
        .
        .
        .
        .