jQuery Grid Plugin – FAQ на основе комментариев

Владимир | | JavaScript, Web разработка.

jqgrid faq

Когда я опубликовал в этом блоге первую статью о jqGrid, то даже приблизительно не представлял насколько актуальной окажется эта тема.

Комментарии посыпались как из рога изобилия 😉 и чтобы ответить на них ушло гораздо больше времени чем на сами статьи. Фактически часть моих статей о jqGrid была ответами на вопросы, заданные к предыдущим статьям.

Но все хорошо знают, что большое количество комментариев прочесть очень сложно, особенно если хочется найти ответ на свой конкретный вопрос 😉 И не удивительно, что через некоторое время вопросы стали повторяться.

Что бы немного улучшить ситуацию, я решил составить этот список.

Но хочу предупредить. Нет никакой гарантии, что ответы, приведенные здесь, подойдут для вашего конкретного случая. Это не официальная документация к плагину. На какие-то вопросы ответы давал я, на какие-то – другие читатели, на какие-то – автор вопроса сам находил ответ. Кроме того, на некоторые вопросы нет развернутых ответов, только подсказки или ссылки на документацию. Также учитывайте, плагин развивается, в новых версиях появляются дополнительные возможности и, возможно, со временем какие-то ответы станут не актуальными.

В общем, не забывайте, что наиболее достоверным источником является официальная документация.

Кстати, если кому-то интересно, в этом блоге опубликовано 7 статей о jqGrid и более 650 комментариев к ним.

Прежде всего, привожу список статей.

jQuery Grid Plugin – «продвинутое» решение для создания таблиц

jqGrid: редактирование табличных данных с помощью inline редакторов

jqGrid – поиск данных

Управление jqGrid с помощью поля с автозавершением

jqGrid – создание дополнительных кнопок

jqGrid, форма с автозавершением и поиск

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

Как изменить размер отображаемой таблицы?

Ширина столбцов указывается при создании таблицы.

jQuery("#list").jqGrid({
…
width:919,
height:230,
…
});

Можете подсказать какое свойство в jqGrid отвечает за размер таблицы? Мне нужно чтобы она занимала всю область выделяемую ей.

Если ширина фиксированная, её можно указать при создании таблицы.
«Плавающих» решений я нашел 2: раз и два.
Оба используют JS, т.е. похоже, что с помощью настроек или только CSS сделать это нельзя.

Как изменить высоту строки, высоту заголовка, а так же их шрифт?

Все эти настройки изменяются с помощью CSS стилей. Например, чтобы изменить размер шрифта в ячейках таблицы, можно использовать правило

.ui-jqgrid tr.ui-row-ltr td {
font-size: 2em;
}

Поддерживает ли jqgrid динамическое изменение количества полей?

На stackoverflow есть обсуждение этой темы.

Вкратце, варианты такие:
1) Каждый раз заново создавать всю таблицу.
2) Загрузить максимально возможное количество полей и прятать/показывать их по мере необходимости.

Как увеличить высоту строки чтобы в ней поместилась длинная запись?

Укажите в colModel для нужного поля параметр

edittype:textarea

Подскажите, как можно разукрасить отдельный столбец в другой цвет?

Есть обсуждение этой темы с решением.

Можно ли фильтр не отображать в некоторых столбцах?

Да, можно. Настройки для каждого столбца указываются отдельно. В параметре colModel.

Как передать при клике по кнопке id текущей строки в php код?

Используйте событие loadComplete.

loadComplete: function(){
	var ids = jQuery("#list").getDataIDs(); 
	for(var i=0;i<ids.length;i++){ 
		var cl = ids[i]; 
		be = "<a href='add_tel.php?id_group="+cl+"' rel="nofollow"gt;Добавить</a>";
		jQuery("#list").setRowData(ids[i],{act:be})
	}
},

Как можно передать GET переменную в таблицу и отправить её на сервер?

Вам нужно определить собственный обработчик события beforeSubmitCell
Он должен вернуть массив с данными, которые будут добавлены к обычным данным ячейки. Т.е. вы можете сформировать массив из данных $_GET и отправить его серверному скрипту.

1) С помощью следующей функции получаем значение нужного параметра

function get_url_param(name)
{ 
	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); 
	var regexS = "[\\?&]"+name+"=([^&#]*)"; 
	var regex = new RegExp( regexS ); 
	var results = regex.exec( window.location.href ); 
	if( results == null )    return ""; 
	else return results[1];
}

(name — имя параметра из GET запроса)
2) в beforeSubmitCell должен быть примерно следующий код

var val=get_url_param('my_param');
return {'my_param':val};

Можно ли с сервера принять дополнительные json данные, во время формирования таблицы?

Попробуйте использовать обработчик afterSaveCell.

Как пишут в справке «This is the ideal place to change other content.» 🙂

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

Откройте jquery.jQgrid.js
В самом начале этого файла устанавливается переменная pathtojsfiles (указывает на папку js) и массив с необходимыми модулями modules.
Путь, указанный в pathtojsfiles объединяется с именем файла, указанным в modules, т.е. вы можете задать любое размещение файлов.

Как можно изменить ширину формы редактирования/добавления записи?

В примерах только

jQuery("#grid_id").editGridRow(rowid, {width:777});

но хочется изменить её ширину для всех вызовов, а не только для этого.

Вариант

ondblClickRow: function(rowid){
	var gr = jQuery("#listobj").getGridParam('selrow');
	if(gr != null) jQuery("#listobj").editGridRow(gr,{width:777});
	else alert("Выберите строку");
}

Не подходит, т.к. в этом случае ширина формы изменяется, но только при возникновении события ondblClickRow, а во всех остальных случаях используется значение по-умолчанию.

Решение.

.navGrid('#pagerobj',{},
{recreateForm:true,height:290,width:400}, // edit
{recreateForm:true,height:290,width:400}, // add 

Перед шириной обязательно нужно указать и высоту.

А не подскажете, как можно сделать автообновление таблицы?

jQuery("#list").trigger("reloadGrid");

Как работает Summary Footer Row?

Код решения (все библиотеки и дамп базы) я упаковал в архив. Надеюсь, поможет.
Кстати, эта возможность работает только в последней версии плагина.

Существует функция tableToGrid(«#mytable»);
которая преобразует html таблицу в jqGrid, а есть обратная возможность?

Насколько я знаю, такой функции нет.
Есть jqGridExport, но она экспортирует настройки таблицы без данных.
Вообще плагин не содержит данных, он их только отображает. За подготовку данных отвечает серверная (php) часть.
Т.е. проще отправить отдельный запрос серверу и написать функцию, которая сформирует таблицу с ними, чем пытаться вытянуть их из jqGrid. Хотя это тоже можно сделать, т.к. jqGrid создает обычную таблицу (вложенную в несколько div'ов) только с большим количеством JS обработчиков.

Можно ли его настроить jqGrid так, чтобы в таблице были заголовочные строки сверху и слева (сводная таблица)?

Да, но придётся передавать в XML все тексты для колонок.

Где можно поменять надпись «Row(s)», которая показывает общее кол-во записей?

В плагин входят файлы локализации, в т.ч. и для русского языка. Т.е. нужно просто подключить этот файл grid.locale-ru.js до плагина.
У меня есть статья в которой показан пример Управление jqGrid с помощью поля с автозавершением.

Кроме того, можно написать свой файл с переводами или использовать такой код

$.jgrid = {
	defaults : {
	recordtext: "View {0} - {1} of {2}",
	emptyrecords: "No records to view",
	loadtext: "Loading...",
	pgtext : "Page {0} of {1}"
},
...
} 

По-сути, этот же способ используется и в файле переводов.

Можно ли управлять таблицей с клавиатуры? Например, входить в режим редактирования, перемещаться по строкам таблицы стрелками и т.п.

Да, можно, но написать кода придётся довольно много.

Нужно установить свои обработчики событий onKeyPress и в них проверять какие клавиши нажаты и вызывать соответствующие методы jqGrid.

Приведите, пожалуйста, какой-нибудь пример реализации перехода на следующую строку по нажатию на стрелку вниз.

При инициализации вашей таблице должно быть указано скрытое поле с ключом ключ

colModel :[
{name:'id', index:'id', width:30, hidden:true,key:true}

Устанавливаем обработчики событий.

window.onkeypress = function(evt){
	evt = (evt) ? evt : ((window.event) ? event : null)
	var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : ((evt.which) ? evt.which : 0));

	if(evt){//если есть событие

	//если клавиша вниз
	if(evt.altKey && charCode == 40){
		var array = jQuery("#list").getDataIDs();//получаем элементы таблицы
		var id = eval (jQuery("#list").getGridParam('selrow')); //получаем номер текущей записи
		for(i in array){//проход по массиву если значение равно выделенному, то получаем значение следующего ключа в массиве
			if (array[i]==id ) {
				i++;
				var next_id = array[i];
				if (next_id == undefined )return;
				jQuery("#list").setSelection(array[i]);
				return;
			}
		}
	}

	//если клавиша вврех
	if(evt.altKey && charCode == 38){
		var array = jQuery("#list").getDataIDs();
		var id = eval(jQuery("#list").getGridParam('selrow'));
		for(i in array){
			if (array[i]==id ) {
				i--;
				var next_id = array[i];
				if (next_id == undefined ) return;
				jQuery("#list").setSelection(array[i]);
				i=array.lenght;
				return;
			}
		}
	}
}

Как сделать множественный фильтр?

Есть статья на эту тему jqGrid – поиск данных.

Есть вопрос по поводу добавления записи в таблицу. Делаю add: true там появляется окошко (там пусто и 2 кнопки), но в это окошко нужно подставить свою форму. Не подскажете как?

Есть хороший пример на эту тему. Находится здесь. В меню справа выбираете Live Data Manipulation — Add row.

Как в jGrid шапку таблицы сделать многострочной?

Например, столбцы заданы следующим образом.

colNames:['ID', 'Дата<br> создания', 'User<br> update<br> last']

Называются столбцы: id, date, uul.

В шапке тыблицы находятся в <div> с уникальным id, который состоит из префикса jqgh_ и имени столбца, например, jqgh_date.

Далее указываем с помощью CSS нужную высоту дива

#jqgh_date, #jqgh_uul {
	height: 3em;
}

Как сохранить настройки сделанные пользователем (тип сортировки , выбранные столбцы, порядок столбцов, размеры и прочее…)?

Существует модуль Import/Export, он позволяет импортировать и экспортировать настройки таблицы.

Есть мнение, что стандартный Import/Export сохраняет много лишней информации.
В этом случае можно использовать методы getGridParam и setGridParam.
param = jQuery("#grid").getGridParam(); //получаем нужные данные
//отправляем на сервер и сохраняем в БД
jQuery("#grid").setGridParam(....); // установим сохраненные данные

Каким образом передать комплексный ключ? И можно ли вместо id использовать как ключ другое поле?

Да, можно.
С помощью extraparam можно передать значения любых полей на сервер. А на серверный скрипт должен выбирать запись используя их.

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

Возьмем пример из документации (Row Editing — Custom edit). Там добавлены три кнопки в первую колонку. Вам нужно добавить только одну, т.е. вставить только один тег input.

В атрибуте onclick передаете id записи. Получить id можно в цикле при вставке кнопок (так же как и в примере).

А окно открываете с помощью window.open()

Как добавить проверку введенных данных перед отправкой на сервер и узнать добавилась ли запись?

Для решения этой задачи в jqGrid предусмотрены специальные события.
Например, для inline редактора подойдет beforeSubmitCell (возникает перед отправкой содержимого ячейки серверу).
Подробное описание в справке (раздел Editing — Sell Editing — Events)
Кроме того, есть события, которые возникают при редактировании записей через отдельную форму.

beforeSubmit: function() {
var ret=[false,"The value is not valid"];
return ret;
},

Как выполнить добавление записи если ссылка на добавление находится не на тулбаре таблицы, а отдельно?

Есть готовый пример. Раздел Manipulating — Grid Data. Там одна из операций «Add row with id 99».

Как спрятать столбец таблицы сразу после её загрузки?

Спрятать столбец можно с помощью параметра hidden:true (подробнее здесь). Кроме того, можно разрешить пользователю самому прятать/показывать колонки (пример здесь).

Как определить номер выделенной строки в таблице? Метода getSelection я не обнаружил в доках.

Я тоже не нашел подходящего метода.
Но когда строка выделена, ей (тегу tr) присваивается класс selected.
Попробуйте использовать что-то вроде

var selRow = $('tr.selected').attr('id'); 

UPD. Tony Tomov нашел подходящий метод

$("#grid").jqGrid('getGridParam','selrow')

и хороший вариант предложил BuCeFaL — использовать событие onSelectRow, которое передает параметр id строки.

Как подключить навигацию к таблице?

Панель навигации включается параметром

pager: jQuery('#pager')

в настройках плагина.

Как сделать, что бы при добавлении новой записи, какие-то значения выставлись в форме по умолчанию (например, текущая дата)?

Значение по-умолчанию можно указать в настройках плагина:

editoptions:{defaultValue:'MAG'}}, 

Можно ли сделать экспорт таблицы в Excel?

Есть готовый пример. Кнопка экспорта появляется в панели навигации под таблицей (рядом с поиском).

В этом примере добавление кнопки выполняется из php скрипта.

С помощью js ее можно добавить так.

$("#mygrid").jqgrid({
...
"excelexport":true,
}); 
Таблица не заполнена данными, с чем это может быть связано? 

Может быть с тем, что сервер возвращает не корректные данные (или в неправильном формате). Устанавливайте firebug (плагин к Firefox) и проверяйте запросы и ответы от сервера.

Как добавить кнопку button на каждую строку, чтобы при нажатии открывалось активное окно в которое передавался бы id элемента строки?

Есть готовый пример (Row Editing -> Custom Edit)

Могу ли я и как с помощью FIREBUG увидеть сформированный sql-запрос? Необходимо для отладки php скрипта, т.к. таблица получает данные в неправильном формате.

Чтобы увидеть запрос firebug'ом, его нужно отправить браузеру. Попробуйте использовать расширение firePHP.
У меня есть две статьи о нём.

1) Программирование на PHP. Использование FirePHP для отладки web приложений.

2) Программирование на PHP. Подключаем FirePHP к фреймворку CodeIgniter.

Альтернативный вариант – создать лог на сервере и записывать данные в него.

При работе с jqGrid использую кодировку windows-1251. При формировании запроса к БД кодировка каким-то образом изменяется и в зарос подставляется параметр в кодировке отличной от windows-1251 (русский текст не читается). Подскажите где искать ошибку?

Дело в том, что jqGrid передает данные в ajax запросе, т.е. они передаются в utf-8. Попробуйте на стороне сервера изменить кодировку запроса. Например, так

$par1 = $this->input->post('par1');
$par1 = mb_convert_encoding($par1,'windows-1251','utf-8');

Как вставить в поле ввода даты календарик?

Для этого можно использовать свойство editoptions для colModel.
Подключение календаря будет выглядеть примерно так

editoptions:{dataInit: function (elem) {$(elem).datepicker({dateFormat:"dd/mm/yy"});} } }

Здесь используется календарик из библиотеки jQuery UI, но вы можете использовать любую другую.

Как сделать горизонтальную прокрутку для таблицы с большим количеством столбцов?

Нужны такие настройки
1) указать ширину столбцов в colModel

colModel :[
{name:'city', index:'city', width:350},
{name:'country', index:'country', width:350}
],

2) указать общую ширину страницы
width: 400,

3) запретить сжатие столбцов
shrinkToFit:false,

Как при добавлении новой записи отправить файл на сервер?

Записи в этом плагине добавляются с помощью AJAX. А файл вы AJAX'ом не отправите.
Подробнее можно почитать здесь.

Как убрать ранее добавленные кнопки? Т.е. нужен метод противоположный «navButtonAdd».

Присвоить заранее Id для кнопки (при ее создании).
Удаление можно выполнить обычным (для jQuery) способом.
$("#xxxxx").remove();

Можно ли форму поиска конструировать самому и в дальнейшем передавать параметры поиска в jqGrid?

Можно используйте appendPostData.
Он позволяет передать дополнительные параметры в запросе.

Интересно почитать.

Хотите стать квалифицированным программистом? Курсы php дадут необходимые вам знания.