jqGrid

31 Январь 2010

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

Начну я с того, что закидаю вас ссылками на блог для скачивания и wiki для установки плагина, а потом покажу как это все сконфигурировать.

Итак для построения таблицы нужны данные, я придумал вот такую JSON рыбу, она статичная так что вам ничего добавить не получиться :P


{"total":1,"records":7,"page":1,
	"rows":[
		{"id":1,"cell":[1,"Москва",55.755786,37.617633,"Yes",["A","B","C"]]},
		{"id":2,"cell":[2,"Киев",50.440951,30.527181,"Yes",["A","B"]]},
		{"id":3,"cell":[3,"Минск",53.905117,27.561184,"Yes",["A","C"]]},
		{"id":4,"cell":[4,"Сан Франциско",37.77493,-122.419416,"No",["B","C"]]},
		{"id":5,"cell":[5,"Нью Йорк",40.714269,-74.005973,"No",["A"]]},
		{"id":6,"cell":[6,"Лондон",51.51333,-0.088947,"Yes",["B"]]},
		{"id":7,"cell":[7,"Наироби",0.878872,37.924805,"Yes",["C"]]}
	]
}

Тут каждая строка описывает имя города, широту, долготу, флажок является ли город столицей и какие-то буквы имитирующие список.

Есть еще словарик


[
{value:"a",name:"A"},
{value:"b",name:"B"},
{value:"c",name:"C"},
{value:"d",name:"D"},
{value:"e",name:"E"}
]

и ответ о успешном добавлении


{"message":"","id":8}

Ну и перед самым интересным еще HTML разметка, она совсем простая и требует задания всего одной таблицы и одного дива.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Example from CTAPbIu_MABP's BLOG</title>

<link rel="stylesheet" type="text/css" media="screen" href="ui-lightness/jquery-ui-1.7.2.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="jqGrid/css/ui.jqgrid.css" />

 
<script src="jquery-1.4.min.js" type="text/javascript"></script>
<-- 
я подключил jquery-ui потому что он и так есть у меня на сайте
его можно не подключать а использовать плагины jqModal и jqDnR
которые можно скачать вместе с jqGrid, подключать и то и то НЕЛЬЗЯ
 -->
<script src="jquery-ui-1.7.2.custom.min.js" type="text/javascript"></script>
    
<script src="jqGrid/js/i18n/grid.locale-ru.js" type="text/javascript"></script>
<script src="jqGrid/jquery.jqGrid.js" type="text/javascript"></script>
<script src="setup.js" type="text/javascript"></script>

</head>
<body>

<table id="table"></table>
<div id="pager"></div>

</body>
</html>

Теперь сам код для создания таблицы, надеюсь слишком просто не будет, все пояснения в коде:


jQuery(document).ready(function($){

	/**
	 * функция для построения select'a из моих данных
	 * тут даже тип ответа нельзя задать
	 * надо все парсить и клеить самому
	 * @param response ответ ajax'a
	 */
	function build(response) {
		// а вот и статья про шаблонизатор пригодилась
		// http://mabp.kiev.ua/2010/01/16/javascript-template-engine/
		var html = '', template = '<option value="[value]">[name]</option>';
		$(eval("("+response.responseText+")")).each(function(i, val){
			html += template.replace(/(\[([^\[\]]+)\])/g, function($0, $1, $2){
			   return val[$2] || "";
			});
		});
		return '<select>' + html + '</select>';
	}

	/**
	 * Эта функция формирует пост запрос и для массивов сформирует
	 * переменную вида letters=a,b,c,d,e
	 * я переделываю это все в letters[]=a,letters[]=b итд
	 * заодно экранирую всякую ересь вроде &<>
	 * @param data массив всех данных формы
	 */
	function serialize(data){
		var str = [];
		if(data.letters)
			data.letters = data.letters.split(",");
		for (var i in data) {
			if ($.isArray(data[i])) {
				for (var j in data[i]) {
					str.push(i + "[]=" + encodeURI(data[i][j]));
				}
			} else {
				str.push(i + "=" + encodeURI(data[i]));
			}
		}
		return str.join("&");
	}


	$("#table").jqGrid({
		autowidth:true,
		colNames:["ID","Name","Latitude","Longitude","Capital","Letters"],
		colModel:[
			// запрещаю редактировать id и искать по нему, по остальным - можно
			{name:"id",			index:"id",				width:40,	editable:false, search:false},
			// тип поля ввода textarea/text/checkbox/select а так же все остальные типы поля input
			{name:"name",		index:"name",			width:100,	editable: true,	edittype:"textarea"},
			// можно так же указать maxlength для инпутов и multiple для селектов
			{name:"latitude",	index:"title",			width:100,	editable: true,	edittype:"text",editoptions:{maxlength:16}},
			{name:"longitude",	index:"description",	width:100,	editable: true,	edittype:"text",editoptions:{maxlength:16}},
			// значения для чекбоксов задаються вот так
			{name:"capital",	index:"capital",		width:100,	editable: true,	edittype:"checkbox",editoptions:{value:"Yes:No"}},
			{name:"letters",	index:"letters",		width:100,	editable: true,
				// для селектов тоже можно задать формат инлайн, но я выбрал кастомный формат
				edittype:"select", editoptions:{multiple:true,dataUrl:"/content/polygon/jqgrid.backend-dict.json",buildSelect:build},
				// и для поиска можно сделать селект
				stype:"select", searchoptions:{dataUrl:"/content/polygon/jqgrid.backend-dict.json", buildSelect:build}
				}
		],
		pager:"#pager",
		datatype:"json",
		viewrecords:true,
		url:"/content/polygon/jqgrid.backend-data.json",
		ajaxGridOptions:{ // <-- передаеться прямо в $.ajax
			type : "GET",
			dataType : "json" // <-- странно но эта опция не перекрывает параметр datatype
		},
		/**
		 * Если пользователь запросил страницу номер которой больше чем максимальное 
		 * количество страниц, или меньше чем 1, эта функция вернет его обратно 
		 * в позволенные рамки
		 */
		onPaging: function(pgButton) {
			var curPage = grid.jqGrid('getGridParam','page');
			var lastPage = grid.jqGrid('getGridParam','lastpage');
				if (curPage < 1) {
			this.p.page = 1;
			}
			if (curPage > lastPage) {
				this.p.page = lastPage;
			}
		}
	}).jqGrid("navGrid","#pager",
		{}, // показать/скрыть кнопки добавить/редактировать/удалить/поиск/обновить
		{  // опции для редактирования
			modal:true, // диалог модальный
			url:"/content/polygon/jqgrid.backend-save.json", // бэкэнд
			closeAfterEdit:true, // закрыть диплог после редактирования
			reloadAfterSubmit:false, // перезагрузить таблицу после добавления
			mtype:"GET", // тип запроса, перекрывает все предыдущие настройки
			/**
			 * с помощью этой функции можно показать ошибки заполнения формы
			 * а так же вставить новый ряд с id который пришел с сервера
			 * error - {"message":"Epic Fail!"}
			 * succes - {"message":""}
			 * @param response
			 */
			afterSubmit:function(response){
				var json = eval("("+response.responseText+")");
				return [!!!json.message,json.message];
			},
			/**
			 * тут я делаю магию: я не хочу что бы можно было редактировать поле letters
			 * поэтому я его дизейблю, но поскольку форма еще не есть частью документа
			 * нельзя сделать выборку $("select")
			 * @param form форма
			 */
			afterShowForm:function(form){
				$("select",form).attr({disabled:"disabled"})
			},
			serializeEditData : serialize // описание функции в начале
		},
		{  // опции для добавления, все так же как и прошлый раз
			modal:true,
			url:"/content/polygon/jqgrid.backend-save.json",
			closeAfterAdd:true, // закрыть диплог после добавления
			reloadAfterSubmit:false,
			mtype:"GET",
			afterSubmit:function(response){
				var json = eval("("+response.responseText+")");
				return [!!!json.message,json.message,json.id];
			},
			/**
			 * Отменяем магию которую сотворила эта же функция при редактировании
			 * @param form форма
			 */
			afterShowForm:function(form){
				$("select",form).removeAttr("disabled");
			},
			serializeEditData : serialize
		},
		{ // опции для удаления
			modal:true,
			url:"/content/polygon/jqgrid.backend-save.json",
			reloadAfterSubmit:false,
			mtype:"GET",
			afterSubmit:function(response){
				var json = eval("("+response.responseText+")");
				return [!!!json.message,json.message];
			},
			serializeDelData : serialize
		},
		{ // опции поиска
			sopt:['eq', 'ne', 'in', 'cn'], // ограничиваю критерии
			multipleSearch:true, // можно искать по нескольким полям
			closeAfterSearch:true // закрыть после поиска
		}
	);
});

Играемся!

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

  1. 31 Январь 2010 в 20:27 | #1
    CTAPbIu_MABP, на самом деле статья, на которую Вы ссылаетесь в самом начале, написана не мной :) чему я очень даже рад! И то, что Вы свою лепту вносите - тоже здорово!
  2. 31 Январь 2010 в 21:35 | #2
    Давно юзеа jqgrid, вот неплохие статьи на русском
  3. 31 Январь 2010 в 22:21 | #3
    @Gennady Поправил @adw0rd спасибо, я его тоже читаю
  4. 31 Январь 2010 в 23:05 | #4
    А сортировка почему не работает? Или так и задумано?))
  5. 31 Январь 2010 в 23:06 | #5
    @slamer сортировка происходит на сервере а там статичный файлик :D
  6. 1 Февраль 2010 в 17:22 | #6
    а почему если я ничего не выбрал при нажатии на "удалить выбранную запись" весь грид дизейблится ?
  7. 1 Февраль 2010 в 17:23 | #7
    тоже самое и с редактированием...
  8. 1 Февраль 2010 в 17:25 | #8
    потому что алерт с сообщением о том что ни одна запись не выбрана позиционируеться неправильно. ищи его на самом верху страницы
  9. 5 Февраль 2010 в 01:01 | #9
    Классно. Очень похоже та Grid из ExtJS. Наверное, скоро это сможет понадобиться. Спасибо ;)
  10. 5 Февраль 2010 в 09:56 | #10
    @Alex Snet да похоже тока код там не такой красивый. я уже у них в репозитории попасся, баги по репортал, советов надавал... в общем там код не очень однородно выглядит
  11. Саня
    14 Февраль 2010 в 17:14 | #11
    Добрый день! У меня есть такая задача: изменение цвета фона/текста, а также шрифта выводимых строк таблицы в соотвествии с заданными в базе данных параметрами, а также возможность клацнув на любую строчку изменить цвет/шрифт. Подскажите, плиз, возможно ли это сделать с помощью этого плагина? Если да, то как? Заранее очень благодарствую за ответы!
  12. 20 Февраль 2010 в 12:11 | #12
    @Саня попробуй метод setRowData
  13. user1231
    9 Апрель 2010 в 18:29 | #13
    Все это очень замечательно.., а вот я например, столкнулся с проблемой... ячейка в формате даты (2010-02-28) так вот .., к примеру нужно сделать поиск по дате не равной(не больше меньше,) а в диапазоне с... по... кто состряпает подобный примерчик ? =)
  14. user1231
    9 Апрель 2010 в 18:31 | #14
    @user1231 только на основе стандартного поиска если возможно.., свою форму создать можно, но не хотелось бы...
  15. 12 Апрель 2010 в 16:14 | #15
    У меня такой вопрос, можно ли на форму добавления строки добавить свои поля которые не будут добавляться а просто будут присутствовать на форма и помогать при выборе данных нужных для заполнения. Например мне надо добавить город и описание для него, но для того что бы его найти в базе мне надо сначала выбрать страну, подгрузить в другой селект регионы, а уж потом города и выбрать нужный
  16. octan
    15 Апрель 2010 в 10:15 | #16
    Добрый день. Кто подскажет как можно добавить дополинтельный буттон в тулбар. Заранее спасибо
  17. 2 Май 2010 в 20:21 | #17
    Привет. А не мог бы прислать демо на почту? Делаю как все объяснил, но кнопки редактирования/удаления не появляются.
  18. 12 Июнь 2010 в 06:56 | #18
    Могли бы вы выложить демо версию, или отправить на эмейл (stanislav@cast.by)? не получается что-то сделать данный пример.
  19. 30 Июль 2010 в 19:05 | #19
    вот спасибо, всё пошло быстрее с живым примером (у разработчиков они какие-то стрёмные, намекают на платную серверную часть)
  20. Hoodognik
    17 Август 2010 в 12:49 | #20
    получил через некоторое время использования сообщение Script Expired помогите пожалста заранее спасибо Hoodognik@vtomske.ru
  21. 17 Август 2010 в 13:27 | #21
    Не могу понять в чем должна заключаться помощь? купить за тебя скритп?
Комментирование отключено.