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