Использование jqGrid вместе с Yii фреймворком

18 марта, 2010
yii php jqgrid

Приветствую всех!

В этой статье речь пойдёт о том как использовать Yii PHP framework и плагин к jQuery под названием jqGrid. Я не буду повторяться и рассказывать о том, что из себя представляют Yii и jqGrid и зачем они нужны. Вы легко найдёте все мои заметки на эту тему с помощью поиска по блогу ;) (кстати, все статьи о Yii вынесены в отдельный раздел).

Когда я проводил этот эксперимент, меня интересовали два момента:

1) подключение jgGrid;

2) преобразование данных, полученных с помощью CActiveDataProvider в формат понятный для jgGrid.

С первым пунктом всё более-менее понятно. jqGrid представляет собой набор JS и CSS файлов, которые нужно подключить к странице.

Для этих целей в Yii предусмотрены специальные методы: registerScriptFile и registerCssFile. Можно, конечно, просто прописать теги script в представлении, но делать этого не рекомендуется, т.к. в этом случае фреймоворк не сможет отслеживать повторные подключения скриптов.

Примечание. Подробнее о работе с JS и CSS файлами можно почитать здесь.

Т.к. я просто экспериментировал, я сделал тестовое представление (testjqgrid.php)

  1. //подключение CSS файлов и JS скриптов
  2. $cs = Yii::app()->clientScript;
  3.  
  4. $cs->registerCssFile(Yii::app()->request->baseUrl.'/jqgrid/css/ui.jqgrid.css');
  5. $cs->registerCssFile(Yii::app()->request->baseUrl.'/jqgrid/css/ui-lightness/jquery-ui-1.7.2.custom.css');
  6.  
  7. $cs->registerScriptFile(Yii::app()->request->baseUrl.'/jqgrid/js/jquery-1.3.2.min.js');
  8. $cs->registerScriptFile(Yii::app()->request->baseUrl.'/jqgrid/js/i18n/grid.locale-ru.js');
  9. $cs->registerScriptFile(Yii::app()->request->baseUrl.'/jqgrid/js/jquery.jqGrid.min.js');
  10. ?>
  11. <table id="list"></table>
  12. <div id="pager"></div>
  13.  
  14. <script type="text/javascript">
  15. $(function() {
  16.     jQuery("#list").jqGrid( {
  17.         url : '<?php echo $this->createUrl('blogs/jqgriddata'); ?>',
  18.         datatype : 'json',
  19.         mtype : 'GET',
  20.         colNames : [ '#', 'Name', 'URL', 'API' ],
  21.         colModel : [ {
  22.             name : 'b_id',
  23.             index : 'b_id',
  24.             width : 60
  25.         }, {
  26.             name : 'b_name',
  27.             index : 'b_name',
  28.             width : 120
  29.         }, {
  30.             name : 'b_url',
  31.             index : 'b_url',
  32.             width : 150,
  33.             align : 'right'
  34.         }, {
  35.             name : 'b_api',
  36.             index : 'b_api',
  37.             width : 80,
  38.             align : 'right'
  39.         } ],
  40.         pager : '#pager',
  41.         rowNum : 10,
  42.         rowList : [ 10, 20, 30 ],
  43.         sortname : 'invid',
  44.         sortorder : 'desc',
  45.         viewrecords : true,
  46.         caption : 'Blogs'
  47.     });
  48. });
  49. </script>

Как видите, сначала мы регистрируем скрипты и файлы стилей, затем вставляем тег для таблицы (строка 12) и тег для панели навигации.

Примечание. В этом примере использован первый попавшийся контроллер (BlogsController). Кроме того, для получения данных используется модель Blogs. Зачем она нужна, в данном случае не принципиально, мы просто будем отображать записи из таблицы с помощью jqGrid.

В конце представления находится код настройки jqGrid. Таблица будет содержать 4 колонки с названиями: «#», «Name», «URL» и «API», а соответствующие поля в таблице имеют названия: «b_id», «b_name», «b_url» и «b_api».

И, конечно, нужно указать адрес скрипта, который будет формировать данные для таблицы (строка 18, параметр url).

Формирование таблицы.

Т.к. jqGrid получает данные с помощью AJAX запросов, то мы добавим два метода в контроллер. Первый – actionJqgrid, будет формировать страницу с таблицей, т.е. просто загружать представление. Второй – actionJqgriddata, предназначен для обработки AJAX запросов.

  1. public function actionJqgrid() {
  2.     $this->render('testjqgrid');
  3. }
  4.  
  5. public function actionJqgriddata() {
  6.     $dataProvider=new CActiveDataProvider('Blogs', array(
  7.         'pagination'=>array(
  8.             'pageSize'=>$_GET['rows'],
  9.             'currentPage'=>$_GET['page']-1,
  10.         ),
  11.     ));
  12.     $responce->page = $_GET['page'];
  13.     $responce->records = $dataProvider->getTotalItemCount();
  14.     $responce->total = ceil($responce->records / $_GET['rows']);
  15.     $rows = $dataProvider->getData();
  16.     foreach ($rows as $i=>$row) {
  17.         $responce->rows[$i]['id'] = $row['b_id'];
  18.         $responce->rows[$i]['cell'] = array($row->b_id, $row->b_name, $row->b_url, $row->b_api);
  19.     }
  20.     echo json_encode($responce);
  21. }

Рассмотрим их подробнее. Как я уже говорил, метод actionJqgrid просто загружает представление. Получать данные из базы нам не нужно, т.к. при создании таблицы jqGrid всё равно отправит AJAX запрос на их получение.

С методом actionJqgriddata ситуация немного сложнее. Дело в том, что нам нужно преобразовать данные, которые возвращает CActiveDataProvider в формат, понятный jqGrid.

Для этого мы создаём объект $responce и в нём сохраняем:

1) page – номер текущей страницы;

2) records – общее количество записей;

3) total – общее количество страниц;

4) rows – массив с данными. Каждый элемент этого массива должен содержать id текущей записи и массив cell с данными ячеек. Этот массив мы формируем с помощью цикла (строки 16-19).

После это преобразовываем $responce в JSON формат и возвращаем браузеру.

Как видите, принцип достаточно простой, но код получается объёмный. В принципе, есть расширение eziiui, которое упрощает работу с jqGrid, но судя по отзывам, оно ограничивает ваши возможности в использовании jqGrid, поэтому я им не пользовался.

Может быть стоит написать расширение, которое будет преобразовывать данные из CActiveDataProvider в JSON формат? Или есть другие идеи?

Полезные ссылки

Блоггер, заходи на новый форум блоггеров, общайся и зарабатывай.

Не бойтесь холода, подберите себе шарфы интернет магазин.

Понравилась статья? Подписывайтесь на продолжение rss link !

Или на мой твиттер twitter link

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в Ajax, JavaScript, PHP, Web разработка, Yii View Comments

]]>
  • BuCeFaL
    Владимир , отлично пишите !
    Спасибо =)
    недавно сам тулил в Yii jqGrid.
    Ваша реализация понравилась намного больше ))
  • Владимир, а как добавить больше функциональности? (данный вариант годится только для отображения) Например, добавление, удаление и прочее??? С оф. сайта пробовал, не получилось, может у Вас есть решение полегче?
  • Читал, пробовал ))) Но все же не совсем то, ибо с Yii получилось только отображение из БД получить, ну да ладно, буду дальше пробовать.
  • В Yii вам нужно создать метод в контроллере, который будет вставлять
    записи. Код метода, такой же как и у отдельного скрипта, только
    библиотека для работы с БД используется другая.
    После этого, проверяйте, куда jqGrid отправляет запросы и с какими данными.
  • andrey
    Спасибо, буду пробовать. По-моему как раз то что нужно. Потом отпишусь о результате
  • andrey
    Владимир, а как можно задать подсказку для заголовка? Все название не вмещается и я его сократил, хочу чтобы в хинте было полное название. Как это можно релизовать?
  • Я бы попробовал использовать какой-нибудь плагин, вроде этого.
    Видел на одном из форумов обсуждение на эту тему, но сам не проверял.
  • pauldee
    Не понял какому классу принадлежит объект $responce
  • stdClass
  • alexy4b
    Не понял( что за класс и в каком месте создаётся объект??
  • stdClass - родовой (общий, generic) php класс. Используется для анонимных объектов, динамических свойств и т.п. Создается автоматически. В данном случае - при вызове
    $responce->page = ...
  • Michael
    А вот как сделать так, что бы заработала сортировка по колонкам?
  • Добавить в CActiveDataProvider (строка 6 в втором листинге) элемент sort и в его параметрах указать настройки сортировки. Параметры jqGrid отправит в $_GET массиве.
blog comments powered by Disqus ]]>