Специально для данной заметки, я подготовил пример использованием разных параметров 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 показать Да или нет