Программирование, веб-кодинг, Расширения, виджеты

Yii2 GridView - виджет таблицы данных

Разбираемся как использовать виджет GridView в своих проектах

Yii2 GridView - виджет таблицы данных

GridView - мощный виджет для вывода ваших данных на сайте в виде таблицы. После автоматической генерации вида модели получается что-то такое:

<?= GridView::widget([
        'dataProvider' => $dataProvider,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'id',
            'name:ntext',
            'url:ntext',
            'image:ntext',
            // 'created_at',
            // 'updated_at',
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>

Выглядит на странице это таблицей

1. Через свойство виджета tableOptions можно изменить класс таблицы

<?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,,
        'tableOptions' => [
            'class' => 'table table-striped table-bordered'
        ],
...

2. Можно задать класс отдельно для строк через свойство rowOptions. В примере ниже используется анонимная функция.

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'rowOptions'=>function ($model, $key, $index, $grid){
        $class=$index%2?'odd':'even';
        return [
            'key'=>$key,
            'index'=>$index,
            'class'=>$class
        ];
    },
]); ?>

3. Можно изменить шаблон вывод gridview с помощью свойства layout

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
'layout'=>"{sorter}\n{pager}\n{summary}\n{items}",
...
]); ?>

4. Свойства showHeader и showFooter - для показа заголовка и футера таблицы

5. emptyCell - для показа чего-то, если ячейки пусты

6. Для кнопок управления тоже можно редактировать template, добавлять свои кнопки или изменять вид у используемых по-умолчанию.

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
         ['class' => 'yii\grid\SerialColumn'],
...
         [
            'class' => 'yii\grid\ActionColumn',
            'header'=>'Действия', 
            'headerOptions' => ['width' => '80'],
            'template' => '{view} {update} {delete}{link}',
        ],
    ],
]); ?>

Можно указывать свойства для каждой собственной кнопки управления через анонимную функцию

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        ...
        [
            'class' => 'yii\grid\ActionColumn',
            'template' => '{view} {update} {delete} {link}',
            'buttons' => [
                'update' => function ($url,$model) {
                    return Html::a(
                    '<span class="glyphicon glyphicon-screenshot"></span>', 
                    $url);
                },
                'link' => function ($url,$model,$key) {
                    return Html::a('Действие', $url);
                },
            ],
        ],
    ],
]); ?>

7. Для каждого атрибута можно указать свои свойства в contentOptions. Это может быть как анонимная функция, так и провто стили.

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        ...
        // Один вариант
        [
            'attribute'=>'parent_id',
            'label'=>'Родительская категория',
            'contentOptions' =>function ($model, $key, $index, $column){
                return ['class' => 'name'];
            },
            'content'=>function($data){
                return "value";
            }
        ],
        // Другой вариант
        [
            'attribute'=>'category_image',
            'contentOptions' =>['class' => 'table_class','style'=>'display:block;'],
            'content'=>function($data){
                return "value";
            }
        ],
        ...
        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>

8. Можно использовать сокращённый формат для атрибута. Будет 'attribute:format:label', где attribute — данные из модели, format — шаблон вывода данных ( 'raw' , 'text' , 'html' , 'image', 'datetime', 'time', 'date', ['date', 'php:Y-m-d'] и другие), label — заголовок столбца. В итоге, код

...
'columns' => [
    ['class' => SerialColumn::className()],
    'name:text:Name',
    ['class' => CheckboxColumn::className()],
]...

9. Чтобы отобразить картинку в ячейке, можно после двоеточия указать тип image у атрибута картинки, либо использовать функцию в value для более широкой настройки.

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
    ...
        // Простой вариант. Автоматическое формирование изображения
        'category_image:image',
        // Второй вариант. Формирование изображения и его параметров через анонимную функцию
        [
            'label' => 'Картинка',
            'format' => 'raw',
            'value' => function($data){
                return Html::img(Url::toRoute($data->category_image),[
                    'alt'=>'yii2 - картинка в gridview',
                    'style' => 'width:15px;'
                ]);
            },
        ],
    ...
    ],
]); ?>

10. Cсылку вывести в GridView можно так же, указав в value для атрибута

...
[
    'label' => 'Ссылка',
    'format' => 'raw',
    'value' => function($data){
        return Html::a(
            'Перейти',
            $data->url,
            [
                'title' => 'Смелей вперед!',
                'target' => '_blank'
            ]
        );
    }
],
... 

11. Связанные модели

// Простой вариант, но без возможности сортировки по полю
 'parent.name',
// Вариант с возможностью сортировки по полю
[
    'attribute'=>'parent_id',
    'label'=>'Родительская категория',
    'format'=>'text', // Возможные варианты: raw, html
    'content'=>function($data){
        return $data->getParentName();
    },
    'filter' => Category::getParentsList()
],

где getParentName() описана в соответствующей модели

public function getParent()
{
    return $this->hasOne(Category::className(), ['id' => 'parent_id']);
}

public function getParentName()
{
    $parent = $this->parent;

    return $parent ? $parent->name : '';
}

12. Вывод даты и времени в GridView

// Самый простой вариант. Доступные модификаторы - date:datetime:time
'created_at:time',
// Расширенный вариант с использованием стандартных шаблонов вывода даты/времени
[
    'attribute'=>'created_at',
    'label'=>'Создано',
    'format'=>'datetime', // Доступные модификаторы - date:datetime:time
    'headerOptions' => ['width' => '200'],
],
// Вариант с явным указанием формата вывода даты/времени
[
    'attribute' => 'updated_at',
    'format' =>  ['date', 'HH:mm:ss dd.MM.YYYY'],
    'options' => ['width' => '200']
],

13. Сделать выпадающий DropDownList в фильтре GridView

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
...
        [
            'attribute'=>'parent_id',
            'label'=>'Родительская категория',
            'format'=>'text', // Возможные варианты: raw, html
            'content'=>function($data){
                return $data->getParentName();
            },
            'filter' => Category::getParentsList()
        ],
...
        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>

и в модели получать список категорий

public static function getParentsList()
{
    // Выбираем только те категории, у которых есть дочерние категории
    $parents = Category::find()
        ->select(['c.id', 'c.name'])
        ->join('JOIN', 'category c', 'category.parent_id = c.id')
        ->distinct(true)
        ->all();

    return ArrayHelper::map($parents, 'id', 'name');
}


Если вам мало возможностей стандартного GridView, предлагаемого разработчиками Yii, посмотрите в сторону навороченного Gridview от kartik-v.


По мотивам – https://nix-tips.ru/yii2-razbiraemsya-s-gridview.html


Читайте также
18 марта 2017
... Программирование, веб-кодинг
Yii2: Ссылки на следующий и предыдущий пост
Полезно под текстом статьи дать ссылки на предыдущую и следующую статью для удобства ориентирования пользователя