Специально для данной заметки, я подготовил пример использованием разных параметров GridView. Исходники модуля и всего приложения, доступны на битбакете.
За основу взять код, полученный при помощи генератора Gii. Типичный код GridView после автоматической генерации:
<?= GridView::widget([
        'dataProvider' => $dataProvider,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],
            'id',
            'parent_id',
            'name:ntext',
            'url:ntext',
            'category_image:ntext',
            // 'created_at',
            // 'updated_at',
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>
В результате получается вполне годный вид:
Однако, всем не угодишь и первоначальный скелет можно очень сильно преобразить, даже не влезая в дебри написания своего GridView.
Настройки таблицы gridview в yii2
По-умолчанию, генерируемая виджетом таблица, имеет класс class=»table table-striped table-bordered». Переопределить класс можно через свойство tableOptions:
<?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,,
        'tableOptions' => [
            'class' => 'table table-striped table-bordered'
        ],
...
Настройки строк gridview yii 2.0
Добавить класс строкам можно через свойство 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
        ];
    },
]); ?>
Шаблон GridView в yii2
По-умолчанию, шаблон GridView содержит информацию об общем количестве записей и отображенных записей summary , саму таблицу с данными items и блок постраничной навигации pager. Настраивается шаблон gridview через свойство layout. Простой пример:
<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
'layout'=>"{sorter}\n{pager}\n{summary}\n{items}",
...
]); ?>
Свойство summary позволяет переопределить соответствующее поле.
Свойства showFooter и showHeader управляют отображением заголовка и футера GridView.
Свойство showOnEmpty разрешает отображение пустой таблицы, в случае отсутствия данных для отображения.
Замена пустых данных в GridView
emptyCell позволяет задать значение для отображения в пустых ячейках.
Отображение управляющих кнопок в GridView
Настройка вывода и вида кнопок в GridView осуществляется указанием класса, шаблона и других параметров столбца.
<?= 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);
                },
            ],
        ],
    ],
]); ?>
Формат данных в столбцах GridView
Для установки своих атрибутов ячейкам таблицы GridView в Yii 2.0, достаточно указать их в параметре contentOptions. Атрибуты могут быть определены как массивом, так и анонимной функцией function ($model, $key, $index, $column), которая может вычислять и возвращать массив атрибутов, таких как class, style, data-key и других.
<?= 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'],
    ],
]); ?>
Сокращенный формат
Yii 2.0 GridView позволяет сократить код настройки поля до вида ‘attribute:format:label’, где attribute — данные из модели, format — шаблон вывода данных (‘raw’ , ‘text’ , ‘html’ , ‘image’, ‘datetime’, ‘time’, ‘date’, [‘date’, ‘php:Y-m-d’] и другие), label — заголовок столбца. В итоге, код
'columns' => [
    ['class' => SerialColumn::className()],
    [
        'class' => DataColumn::className(), // Не обязательно
        'attribute' => 'name',
        'format' => 'text',
        'label' => 'Name',
    ],
    ['class' => CheckboxColumn::className()],
]
можно сократить до
'columns' => [
    ['class' => SerialColumn::className()],
    'name:text:Name',
    ['class' => CheckboxColumn::className()],
]
Класс DataColumn::className() присваивается автоматически, если он не указан. Формат данных обрабатывается formatter, используемым GridView. По-умолчанию это yii\i18n\Formatter.
Картинка в Yii 2.0 GridView
Отобразить картинку в GridView можно несколькими способами:
Самый простой: указать тип поля после двоеточия ‘categoryImagePath:image’. Второй вариант — расширенная настройка поля.
<?= 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;'
                ]);
            },
        ],
    ...
    ],
]); ?>
Ссылка в GridView
Настроим поле для вывода ссылки из модели.
...
[
    'label' => 'Ссылка',
    'format' => 'raw',
    'value' => function($data){
        return Html::a(
            'Перейти',
            $data->url,
            [
                'title' => 'Смелей вперед!',
                'target' => '_blank'
            ]
        );
    }
],
...
Данные из связанных моделей в GridView
Связанные данные выводятся аналогично данным самой модели.
// Простой вариант, но без возможности сортировки по полю
 'parent.name',
// Вариант с возможностью сортировки по полю
[
    'attribute'=>'parent_id',
    'label'=>'Родительская категория',
    'format'=>'text', // Возможные варианты: raw, html
    'content'=>function($data){
        return $data->getParentName();
    },
    'filter' => Category::getParentsList()
],
В модели Category описаны соответствующие методы.
public function getParent()
{
    return $this->hasOne(Category::className(), ['id' => 'parent_id']);
}
public function getParentName()
{
    $parent = $this->parent;
    return $parent ? $parent->name : '';
}
Вывод даты и времени в GridView
Отобразить данные в формате даты/времени можно либо прямым указанием типа данных для вывода ‘created_at:datetime’, ‘created_at:date’, ‘created_at:time’ или с использованием расширенного варианта.
// Самый простой вариант. Доступные модификаторы - 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']
],
DropDownList в фильтре GridView Yii 2.0
По-умолчанию, GridView использует текстовый фильтр. Для создания фильтра в виде выпадающего меню, достаточно указать массив значений, по которым будет производиться фильтрация в параметре filter. Сортировка и фильтр данных по связанным полям уже описана в соответствующей заметке.
Массив можно задать вручную или получать из модели.
<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
...
        [
            'attribute'=>'isactive',
            'filter'=>array("1"=>"Активно","2"=>"Не активно"),
        ],
...
        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>
Второй вариант
<?= 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');
}
Заключение
Стандартный виджет Yii2 фреймворка GridView имеет богатые возможности для отображения данных. Возможно как отображение «сырых» данных, так и вычисление их на лету, при помощи анонимных функций. Размещение активного содержимого в ячейках GridView будет описано в другом материале.


Спасибо! Очень полезно написано, куда интереснее чем читать мануалы.
Как мне изменить ширина колонки в gridView?
‘options’ => [‘width’ => ’70’]
Большое спасибо, все качественно и понятно!
Спасибо огромное, что собрал всю информацию в наглядном виде по GRIDу.
Большая просьба, сделай такую же инфу по view. Волнует использование Nested Layouts и Blocks в структуре Views.
Заранее огромное спасибо)!
Большое спасибо за материал!
Хотелось бы еще увидеть как поэтапно сделать такой же левый sidebar
Большое спасибо за отличный материал! ^^
Ресспект и уважуха аффтору!
Спасибо, добрый человек! Все что нужно нашел в Вашей статье! В закладки по любому!
Отличный материал, большое спасибо за публикацию!
спасибо! все классно расписано.
Здравствуйте! Подскажите как изменить стиль полей фильтра? По умолчанию слишком большой padding стоит и не видно значение фильтра :(
Доброго времени суток!
у Html::activeDropDownList() можно выставить такую штуку ‘prompt’=>’— Укажите группу — ‘
а как подобное реализовать в простом
‘filter’ => array(
‘val1’=>’name1’
)
?
заранее спасибо!
используйте Html::dropDownList() для фильтра
Доброго дня, я прочитав статтю з задоволенням
дякую
Скажите пожалуйста, как выглядит примерный route для этого куска кода:
Html::img(Url::toRoute($data->category_image)
Url::toRoute() — вот это меня интересует, как это работает? По идее он должен сгенерировать правильный URL для статики-картинки? А как выглядит сам роут тогда?
Роут (маршрут) — путь до действия, которое нужно вызвать — модуль/контроллер/действие.
Для статичных изображений используй Url::to().
Если $data->category_image == ‘images/cat_image.jpg’, тогда Url::to(‘@web/’ . $data->category_image) == ‘/images/cat_image.jpg’.
Для создания абсолютного пути Url::to(‘@web/’ . $data->category_image, true) == ‘http://site.ru/images/cat_image.jpg’
Господа. Не забываем
‘target’ => ‘_blank’
rel=»noopener noreferrer».
Подскажите пожалуйста, что за переменная $data в анонимной функции?
Все просто. Идем в доку и видим, какие параметры передаются анонимной функции.
Подскажите, как в сокращенном формате
attribute:format:label
вывести decimal с двумя знаками после запятой:
[
‘label’ => ‘Summ’,
‘attribute’ => ‘summ’,
‘format’ => [‘decimal’, 2]
],
Никак, если не переделать метод createDataColumn().
Кто подскажет как убрать номера строк (1 колонка) в GridView?
Просто удали строку [‘class’ => ‘yii\grid\SerialColumn’].
Через стандартно сгенерированный через gii CRUD с gridView содержимое ячейки отображается в одну строку. Если текста много — появляется длинющий скрол. Подскажите как сделать нормальное отображение с переносом текста.
Решил проблему, через ‘options’ => [‘width’ => ’70’].
Спасибо за статью, она реально крутая.
при такой выборке со свзяанной моделью return $data->getCategoryName(); получается очень много запросов БД, каждая итерация делает запрос, можно как-то пофиксить?
Стало быть нужно связи в запросе к БД наводить. В модели поиска в методе search() нужно запрос дополнить. Примерно так:
public function search($params) {
$query = Classes::find()
->select([‘CONCAT_WS(«—», DATE_FORMAT(s.begin_time, «%Y»), DATE_FORMAT(s.end_time, «%y»)) AS season_label’, ‘c.*’])
->from([«c» => Classes::tableName()])
->innerJoin([«s» => Seasons::tableName()], «c.season_id = s.id»);
Вдруг кому-то пригодится, написал так.
[
‘attribute’ => ‘department_id’,
‘filter’ => Model::getList(), // Массив [ ‘id’ => ‘name’ ]
‘content’ => function ($model, $key, $index, $column){
return $column->filter[$model->department_id];
}
]
Valkinaz, пригодилось )). Спасибо, Вам очень помогли
Не за что, единственное, поторопился отправить тогда, а редактировать уже нельзя.
Model::getList() стоит вынести в отдельную переменную, а уже потом ее использовать, чтобы не было запросов на каждой записи.
спасибо,очень хорошая статья
Приветствую Вас уважаемый Nix! Спасибо за хорошую статью и весь сайт в целом!
Возник такой вопрос, сделал в гриде DropDown по второму варианту (только выборка идёт из этой же базы, полю делаю GROUP BY). А как мне значению по умолчанию, пустое поле чтобы выводить все записи, добавить описание?
Т.е. [‘prompt’ => ‘Все’] навесить на первый элемент списка?
Нашел пример такой:
‘filter’ => Html::dropDownList(‘PostsSearch[active]’,
…………
[
‘prompt’ => ‘Все’
]),
Но не понимаю как тут передать данные Category::getParentsList() в dropDownList :(
Может быть в Вашем примере есть возможность добавить этот «prompt»?
Примерно так:
'filter' => Html::activeDropDownList($searchModel, 'parent_id', Category::getParentsList(), ['prompt' => 'Все'])Подробнее в мануале.
Спасибо за статью. То что надо!
Подскажите пожалуйста, как редактировать данные таблицы напрямую? Нужно просто нажать 2 раза на нужную строку после чего ее можно изменить прямо в таблице. Нигде не могу найти подобную инструкцию =(
Есть ли подобная магия для DetailView widget
Спасибо большое за статью!!! Была очень полезна
Очень интересно, подробно и красиво.
Спасибо за статью.
А как вывести в gridview посты из дочерних категорий при выборе родительской? т.е. именно посты на странице постов выводятся с фильтром по категориям, но при выборе в фильтре родительской отображаются только посты родительской, а хотело8сь бы получить все посты дочерних категорий
очень круто!
Хорошая статья, спасибо! Хотелось бы мне её немного еще увеличить.
А как делать такое
У меня в базе поле active добавляется Y или N
как в GridView показать Да или нет