Спонсор поста: EximusCommerce — платформа для создания интернет-магазинов на Yii framework.
Продолжаем знакомиться с виджетами в Yii framework. Сегодня рассмотрим CGridView. CGridView — это стандартный виджет, располагается в /framework/zii/widgets/grid/CGridView.php. Виджет служит, для отображения данных в табличной форме. Поддерживается сортировка по атрибутам, постраничная навигация и поиск. Сортировка и постраничная навигация могут осуществляться, как с помощью AJAX’а, так и без него. Если, у пользователя отключен javascript, то сортировка и переключение страниц будет происходить обычным образом, без AJAX.
Минимальный код необходимы для вызова виджета:
$dataProvider=new CActiveDataProvider('Model'); $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider'=>$dataProvider, ));
Под катом, мы рассмотрим следующие пункты:
1. Добавление календаря в фильтры (jquery datepicker).
2. Выпадающие списки в фильтрах.
3. Изменение дизайна.
Все действия будут производиться на немного измененном демо-блоге, который можно скачать вместе с Yii. В конце статьи будет архив с готовым примером.
Создадим таблицу tbl_news с такой структурой:
name — название новости.
content — содержимое новости.
status — статус новости. Новости с 0 статусом не показываются.
created_at — дата создания новости.
SQL:
CREATE TABLE `tbl_news` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `content` text NOT NULL, `status` tinyint(1) NOT NULL DEFAULT '1', `created_at` date DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ; -- -- Дамп данных таблицы `tbl_news` -- INSERT INTO `tbl_news` (`id`, `name`, `content`, `status`, `created_at`) VALUES (1, 'name1', 'content1', 1, '2013-03-23'), (2, 'name2', 'content2', 1, '2013-04-01'), (3, 'name3', 'content3', 0, '2013-04-03'), (4, 'name4', 'content4', 1, '2013-04-01'), (5, 'name5', 'content5', 0, '2013-04-05');
После того, как создали таблицу tbl_news в базе данных, генерируем модель News, с помощью gii. Если все прошло правильно, то новая модель доступна в models/News.php. Изменим немного метод search. Меняем:
return new CActiveDataProvider($this, array( 'criteria'=>$criteria, ));
На следующий код:
return new CActiveDataProvider($this, array( 'criteria'=>$criteria, 'pagination'=>array( 'pageSize'=>10, ), sort'=>array( 'defaultOrder'=>array( 'created_at'=>"DESC" )) ));
В приведенном выше коде, задается, что на странице будет выводится 10 записей и сортировка будет по полю created_at.
Создадим контроллер NewsController.php в protected/controllers (CRUD-методы специально не включены в контроллер).
Содержимое NewsController:
<?php class NewsController extends Controller { /** * Главная страница новостей */ public function actionIndex() { $model = new News('search'); $model->unsetAttributes(); if(isset($_GET['News'])) { $model->attributes = $_GET['News']; } $this->render('index', array('model'=>$model)); } } ?>
Создаем директорию news в protected/views и представление index.php в views/news. В файле index.php будут выводится все новости в виджете CGRidView.
Содержимое index.php:
<?php $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider' => $model->search(), 'filter' => $model, 'columns' => array( array( 'name' => 'name', 'type' => 'raw', 'value' => '$data->name', ), array( 'name' => 'status', 'type' => 'raw', 'value' => '$data->status', ), array( 'name' => 'created_at', 'type' => 'raw', 'value' => '$data->created_at', ), array( 'class' => 'CButtonColumn', 'template' => '{update} {delete}', 'buttons' => array( 'update' => array( //здесь должен быть url для редактирования записи 'url' => 'Yii::app()->createUrl("/edit/$data->id")', ), 'delete' => array( //здесь должен быть url для удаления записи 'url' => 'Yii::app()->createUrl("/delete/$data->id")', ), ), ), ), ));
Открыв страницу с новостями, вы увидите 5-ть записей в таблице, со стандартным оформлением. Можно производить сортировку по атрибутам, искать значения в фильтрах, но для того, чтобы найти записи за определенную дату нужно вводить значение вручную. Это не слишком удобно. Исправим это, добавив календарь для поля created_at.
Добавление календаря в CGridView
Заменяем:
array( 'name' => 'created_at', 'type' => 'raw', 'value' => '$data->created_at', ),
На следующий код:
array( 'name' => 'created_at', 'type' => 'raw', 'value' => '$data->created_at', 'filter'=>$this->widget('zii.widgets.jui.CJuiDatePicker', array( 'model'=>$model, 'attribute'=>'created_at', 'language'=>'ru', 'options'=>array( 'showAnim'=>'fold', 'dateFormat'=>'yy-mm-dd', 'changeMonth' => 'true', 'changeYear'=>'true', ), ),true), ),
Теперь, при клике в поле фильтра для created_at, будет появляться календарь с возможностью выбора даты. Чтобы, datepicker работал и после выполнения ajax-запросов, нужно добавить следующий код после columns:
'afterAjaxUpdate'=>"function() { jQuery('#News_created_at').datepicker(jQuery.extend(jQuery.datepicker.regional['ru'],{ 'showAnim':'fold', 'dateFormat':'yy-mm-dd', 'changeMonth':'true', 'changeYear':'true'})); }",
Добавление выпадающего списка в CGridView
Изменим код колонки status’а на следующий:
array( 'name' => 'status', 'type' => 'raw', 'value' => '$data->getStatus($data->status)', 'filter' => array(''=>'Все', 1 => 'Показывается', 0=> 'Не показывается'), ),
Кроме измененного фильтра, был добавлен метод getStatus() для возвращения значения статуса. Данный метод нужно добавить в модель News.
public function getStatus($status) { $data = array(0=>"Не показывается", 1=>"Показывается"); return $data[$status]; }
Добавление своих стилей в CGridView
Если посмотреть на страницу новостей после изменений, то можно увидеть, что текстовое поле под колонкой «Статус» заменено на выпадающий список. Вместо 1 и 0, выводятся текстовые значения статуса. Осталось изменить кнопки для редактирования, удаления записей и стили. Добавьте следующие стили в файл main.css (входит в комплект с демо блогом):
.table-striped td { border-top: 1px solid #DDDDDD; line-height: 20px; padding: 8px; text-align: left; vertical-align: top; } .grid-view table.table-striped th { padding-bottom: 8px; } .table-striped { width: 100%; } .table-striped th { background: #ffffff; text-align: center; } .grid-view table.table-striped tr.selected { background-color: #BCE774 !important; } .grid-view table.table-striped { border-collapse: collapse; }
В views/news/index.php после ‘filter’ => $model добавляем ‘itemsCssClass’=>’table-striped’. Этим мы указали значение для атрибута class, для нашей таблицы. Изменим кнопки, для удаления и редактирования.
Для редактирования будет такая картинка:
Для удаления, вот такая:
Обе картинки находятся в директории images. Предварительно ее нужно создать, если ее нет.
В ‘update’, перед url, добавляем: ‘imageUrl’=>’/images/edit.png’, а в ‘delete’ ‘imageUrl’=>’/images/delete.png’,
Должно получиться вот так:
array( 'class' => 'CButtonColumn', 'template' => '{update} {delete}', 'buttons' => array( 'update' => array( //url до картинки 'imageUrl'=>'/images/edit.png', //здесь должен быть url для редактирования записи 'url' => 'Yii::app()->createUrl("/edit/$data->id")', ), 'delete' => array( //url до картинки 'imageUrl'=>'/images/delete.png', //здесь должен быть url для удаления записи 'url' => 'Yii::app()->createUrl("/delete/$data->id")', ), ), ),
Для того, чтобы все изменения вступили в силу, нужно очистить директорию assets. Кнопки задаются по шаблону, определенному в ‘template’ => ‘{update} {delete}’. В скобках можно задать шаблон для своей кнопки, а потом добавить ее в массив buttons.
Полный листинг файла news/index.php:
<?php $this->widget('zii.widgets.grid.CGridView', array( 'dataProvider' => $model->search(), 'filter' => $model, 'itemsCssClass'=>'table-striped', 'columns' => array( array( 'name' => 'name', 'type' => 'raw', 'value' => '$data->name', ), array( 'name' => 'status', 'type' => 'raw', 'value' => '$data->getStatus($data->status)', 'filter' => array(''=>'Все', 1 => 'Да', 0=> 'Нет'), ), array( 'name' => 'created_at', 'type' => 'raw', 'value' => '$data->created_at', 'filter'=>$this->widget('zii.widgets.jui.CJuiDatePicker', array( 'model'=>$model, 'attribute'=>'created_at', 'language'=>'ru', 'options'=>array( 'showAnim'=>'fold', 'dateFormat'=>'yy-mm-dd', 'changeMonth' => 'true', 'changeYear'=>'true', ), ),true), ), array( 'class' => 'CButtonColumn', 'template' => '{update} {delete}', 'buttons' => array( 'update' => array( //url до картинки 'imageUrl'=>'/images/edit.png', //здесь должен быть url для редактирования записи 'url' => 'Yii::app()->createUrl("/edit/$data->id")', ), 'delete' => array( //url до картинки 'imageUrl'=>'/images/delete.png', //здесь должен быть url для удаления записи 'url' => 'Yii::app()->createUrl("/delete/$data->id")', ), ), ), ), 'afterAjaxUpdate'=>"function() { jQuery('#News_created_at').datepicker(jQuery.extend(jQuery.datepicker.regional['ru'],{ 'showAnim':'fold', 'dateFormat':'yy-mm-dd', 'changeMonth':'true', 'changeYear':'true'})); }", ));
В статье показаны лишь немногие методы доступные для CGridView. Подробное описание доступно на официальном сайте.
Архив с примером. Новости из примера, запускаются по адресу: http://yiiblog/news.
- Пример работы с CListView в Yii
- Примеры работы с миграциями в Yii framework
- Yii, Модуль SRBAC часть 2. Пишем регистрацию.
- Yii модуль srbac, Часть 1
- Активация аккаунта Yii
Теги: Yii
Подход с непосредственным вписыванием раз за разом десятков одних и тех же параметров в каждый грид не очень удобен. Можно вынести стили грида http://www.elisdn.ru/blog/36/yii-widgets-styling-approaches и кнопок
http://www.elisdn.ru/blog/37/custom-cgridview-columns-in-yii в сторонние файлы и вернуться почти к тому же минимальному коду.
Reply
Вы проводите обучение по Yii?
Reply
Max Reply:
Январь 22, 2014 at 22:55
Нет.
Reply