Использование 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)

//подключение CSS файлов и JS скриптов
$cs = Yii::app()->clientScript;

$cs->registerCssFile(Yii::app()->request->baseUrl.'/jqgrid/css/ui.jqgrid.css');
$cs->registerCssFile(Yii::app()->request->baseUrl.'/jqgrid/css/ui-lightness/jquery-ui-1.7.2.custom.css');

$cs->registerScriptFile(Yii::app()->request->baseUrl.'/jqgrid/js/jquery-1.3.2.min.js');
$cs->registerScriptFile(Yii::app()->request->baseUrl.'/jqgrid/js/i18n/grid.locale-ru.js');
$cs->registerScriptFile(Yii::app()->request->baseUrl.'/jqgrid/js/jquery.jqGrid.min.js');
?>
<table id="list"></table>
<div id="pager"></div> 

<script type="text/javascript">
$(function() {
	jQuery("#list").jqGrid( {
		url : '<?php echo $this->createUrl('blogs/jqgriddata'); ?>',
		datatype : 'json',
		mtype : 'GET',
		colNames : [ '#', 'Name', 'URL', 'API' ],
		colModel : [ {
			name : 'b_id',
			index : 'b_id',
			width : 60
		}, {
			name : 'b_name',
			index : 'b_name',
			width : 120
		}, {
			name : 'b_url',
			index : 'b_url',
			width : 150,
			align : 'right'
		}, {
			name : 'b_api',
			index : 'b_api',
			width : 80,
			align : 'right'
		} ],
		pager : '#pager',
		rowNum : 10,
		rowList : [ 10, 20, 30 ],
		sortname : 'invid',
		sortorder : 'desc',
		viewrecords : true,
		caption : 'Blogs'
	});
});
</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 запросов.

public function actionJqgrid() {
	$this->render('testjqgrid');
}

public function actionJqgriddata() {
	$dataProvider=new CActiveDataProvider('Blogs', array(
		'pagination'=>array(
			'pageSize'=>$_GET['rows'],
			'currentPage'=>$_GET['page']-1,
		),
	));
	$responce->page = $_GET['page'];
	$responce->records = $dataProvider->getTotalItemCount();
	$responce->total = ceil($responce->records / $_GET['rows']);
	$rows = $dataProvider->getData();
	foreach ($rows as $i=>$row) {
		$responce->rows[$i]['id'] = $row['b_id'];
		$responce->rows[$i]['cell'] = array($row->b_id, $row->b_name, $row->b_url, $row->b_api);
	}
	echo json_encode($responce);
}

Рассмотрим их подробнее. Как я уже говорил, метод 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 Комментарии (25) »

]]>

Вы можете оставить комментарий. Трекбеки закрыты.

  • Michael

    А вот как сделать так, что бы заработала сортировка по колонкам?

    • http://www.simplecoding.org/ Владимир

      Добавить в CActiveDataProvider (строка 6 в втором листинге) элемент sort и в его параметрах указать настройки сортировки. Параметры jqGrid отправит в $_GET массиве.

  • Michael

    А вот как сделать так, что бы заработала сортировка по колонкам?

    • http://www.simplecoding.org/ Владимир

      Добавить в CActiveDataProvider (строка 6 в втором листинге) элемент sort и в его параметрах указать настройки сортировки. Параметры jqGrid отправит в $_GET массиве.

  • pauldee

    Не понял какому классу принадлежит объект $responce

    • http://www.simplecoding.org/ Владимир

      stdClass

  • pauldee

    Не понял какому классу принадлежит объект $responce

    • http://www.simplecoding.org/ Владимир

      stdClass

  • andrey

    Владимир, а как можно задать подсказку для заголовка? Все название не вмещается и я его сократил, хочу чтобы в хинте было полное название. Как это можно релизовать?

    • http://www.simplecoding.org/ Владимир

      Я бы попробовал использовать какой-нибудь плагин, вроде этого.
      Видел на одном из форумов обсуждение на эту тему, но сам не проверял.

  • andrey

    Владимир, а как можно задать подсказку для заголовка? Все название не вмещается и я его сократил, хочу чтобы в хинте было полное название. Как это можно релизовать?

    • http://www.simplecoding.org/ Владимир

      Я бы попробовал использовать какой-нибудь плагин, вроде этого.
      Видел на одном из форумов обсуждение на эту тему, но сам не проверял.

  • andrey

    Спасибо, буду пробовать. По-моему как раз то что нужно. Потом отпишусь о результате

  • andrey

    Спасибо, буду пробовать. По-моему как раз то что нужно. Потом отпишусь о результате

  • http://www.idkaznet.kz/ Одиночка Айс

    Владимир, а как добавить больше функциональности? (данный вариант годится только для отображения) Например, добавление, удаление и прочее??? С оф. сайта пробовал, не получилось, может у Вас есть решение полегче?

  • http://www.simplecoding.org Владимир
  • http://www.idkaznet.kz/ Одиночка Айс

    Читал, пробовал ))) Но все же не совсем то, ибо с Yii получилось только отображение из БД получить, ну да ладно, буду дальше пробовать.

  • http://www.simplecoding.org Владимир

    В Yii вам нужно создать метод в контроллере, который будет вставлять
    записи. Код метода, такой же как и у отдельного скрипта, только
    библиотека для работы с БД используется другая.
    После этого, проверяйте, куда jqGrid отправляет запросы и с какими данными.

  • alexy4b

    Не понял( что за класс и в каком месте создаётся объект??

  • http://www.simplecoding.org Владимир

    stdClass – родовой (общий, generic) php класс. Используется для анонимных объектов, динамических свойств и т.п. Создается автоматически. В данном случае – при вызове
    $responce->page = …

  • BuCeFaL

    Владимир , отлично пишите !
    Спасибо =)
    недавно сам тулил в Yii jqGrid.
    Ваша реализация понравилась намного больше ))

  • Mgs3bg

    А вот как сделать так, что бы заработал jQuery("#list").jqGrid('filterToolbar', {stringResult: true, searchOnEnter: false, defaultSearch : "cn"});
    что нада добавит в CActiveDataProvider.
    для сортировка заработат вот:
    public function actionJqgriddata() {
        $sidx = $_GET['sidx']; // get index row – i.e. user click to sort
        $sord = $_GET['sord']; // get the direction
       
            $dataProvider=new CActiveDataProvider('Delme', array(
                'pagination'=>array(
                    'pageSize'=>$_GET['rows'],
                    'currentPage'=>$_GET['page']-1,
                ),
                'sort'=>array(
                'defaultOrder'=>"$sidx $sord"
            )
           
           
           
           
            ));
    pls помогите, спосибо!

    • http://www.simplecoding.org Владимир

      Т.е. вы хотите реализовать поиск?
      По-умолчанию CActiveDataProvider вызывает метод findAll, который возвращает все записи под ряд. Вам нужно вызвать метод setCriteria и передать ему объект CDbCriteria, а в нём указать параметры поиска.

  • http://buzzman.ru/ Nikita

    Парни, подскажите, пожалуйста, по сортировке в jqGrid – есть столбец "Num" (например), как данные отсортировать так, чтобы сначала шли строки со значением 1,2,3,…20..50, а потом строки с пустым значением NUM. Сейчас, просто напросто, если установить сортировку в ASC сначала идут записи с пустыми ячейками, а потом только с номера от 1 и далее. Спасибо заранее.

    • http://www.simplecoding.org Владимир

      У меня есть статья по сортировке – попробуйте использовать пример с сортировкой числового поля по правилам текстового.
      Результат не гарантирую :)
      Возможно, будет проще и быстрее вытянуть данные двумя запросами.

]]>
Tweet