yii2cactivedataprovideryii-widgets

How to show records in section with heading from activeDataProvider in yii2


My database structure is as follows

id :    item    :    name   : price
1  : framework  : bootstrap : 90
1  : framework  : zend : 100
1  : framework  : drupal : 150
1  : responsive : no        : 0
1  : responsive : yes       : 50

I want to render result as rows which have same item must have that item name as section heading and rest of the data should be displayed under that section as

FRAMEWORK

Name      : Price
Bootstrap : 90
Zend      : 100
Drupal    : 150

RESPONSIVE

Name    : Price
None    : 0
Yes     : 50

How can i done this with active data provider, data widgets or there may be another method


Solution

  • i suggest you override GridView's renderTableRow. if you detect a value-change on the column you want to group, just insert a custom group heading row.

    <?php
    class GroupGridView extends \yii\grid\GridView 
    {
        public $groupingColumn = null;
        public $groupingText   = null;
    
        public function renderTableRow ($model, $key, $index)
        {
            if ($this->groupingColumn == null)
                return parent::renderTableRow($model, $key, $index);
    
            $models = $this->dataProvider->models;
            $result = '';
            if ($index < count($models) - 1 && ($index == 0 || $models[$index][$this->groupingColumn] != $models[$index + 1][$this->groupingColumn])) {
                $result = sprintf('<tr class="grouping"><td colspan="%d">%s</td></tr>', count($this->columns), ($this->groupingText == null ? $models[$index]->{$this->groupingColumn} : (is_callable($this->groupingText) ? call_user_func($this->groupingText, $model, $key, $index) : $this->groupingText)));
            }
            return $result . parent::renderTableRow($model, $key, $index);
        }
    }
    
    $dataProvider = new \yii\data\ActiveDataProvider([
        'query'      => \common\models\Task::find()->orderBy(['customer_id' => SORT_ASC]),
        'pagination' => [
            'pageSize' => 100,
        ],
    ]);
    
    echo GroupGridView::widget([
        'groupingColumn' => 'item',
        'groupingText' => function($model, $key, $index) {
            return sprintf('--- %s --- %s --- %d', $model->item, $key, $index);
        },
        'dataProvider'   => $dataProvider
    ])
    
    ?>
    

    keep in mind that you have to sort by the grouping column.