jqGrid

Это переработаная статья о плагине под названием jqGrid, тут раньше были какие-то ссылки но они больше не работают, поэтому я оставил только пример.

Начну я с того, что закидаю вас ссылками на страницу для скачивания и 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 разметка, она совсем простая и требует задания всего одной таблицы и одного дива.


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

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


jQuery(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: "/examples/json/jqgrid/dict.json", buildSelect: build},
				// и для поиска можно сделать селект
				stype: "select", searchoptions: {dataUrl: "/examples/json/jqgrid/dict.json", buildSelect: build}
			}
		],
		pager: "#pager",
		datatype: "json",
		viewrecords: true,
		url: "/examples/json/jqgrid/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: "/examples/json/jqgrid/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: "/examples/json/jqgrid/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: "/examples/json/jqgrid/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 // закрыть после поиска
		}
	);
});

Играемся!

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

22 Комментарии “jqGrid

  1. CTAPbIu_MABP, на самом деле статья, на которую Вы ссылаетесь в самом начале, написана не мной :) чему я очень даже рад! И то, что Вы свою лепту вносите — тоже здорово!

  2. а почему если я ничего не выбрал при нажатии на «удалить выбранную запись» весь грид дизейблится ?

  3. потому что алерт с сообщением о том что ни одна запись не выбрана позиционируеться неправильно. ищи его на самом верху страницы

  4. Классно. Очень похоже та Grid из ExtJS.
    Наверное, скоро это сможет понадобиться.
    Спасибо ;)

  5. @Alex Snet
    да похоже
    тока код там не такой красивый. я уже у них в репозитории попасся, баги по репортал, советов надавал… в общем там код не очень однородно выглядит

  6. Добрый день! У меня есть такая задача: изменение цвета фона/текста, а также шрифта выводимых строк таблицы в соотвествии с заданными в базе данных параметрами, а также возможность клацнув на любую строчку изменить цвет/шрифт.
    Подскажите, плиз, возможно ли это сделать с помощью этого плагина? Если да, то как?
    Заранее очень благодарствую за ответы!

  7. Все это очень замечательно..,
    а вот я например, столкнулся с проблемой…
    ячейка в формате даты (2010-02-28)
    так вот .., к примеру нужно сделать поиск по дате не равной(не больше меньше,)
    а в диапазоне с… по…
    кто состряпает подобный примерчик ? =)

  8. @user1231
    только на основе стандартного поиска если возможно.., свою форму создать можно, но не хотелось бы…

  9. У меня такой вопрос, можно ли на форму добавления строки добавить свои поля которые не будут добавляться а просто будут присутствовать на форма и помогать при выборе данных нужных для заполнения. Например мне надо добавить город и описание для него, но для того что бы его найти в базе мне надо сначала выбрать страну, подгрузить в другой селект регионы, а уж потом города и выбрать нужный

  10. Добрый день. Кто подскажет как можно добавить дополинтельный буттон в тулбар. Заранее спасибо

  11. Привет. А не мог бы прислать демо на почту? Делаю как все объяснил, но кнопки редактирования/удаления не появляются.

  12. Могли бы вы выложить демо версию, или отправить на эмейл (stanislav@cast.by)?
    не получается что-то сделать данный пример.

  13. вот спасибо, всё пошло быстрее с живым примером (у разработчиков они какие-то стрёмные, намекают на платную серверную часть)

  14. получил через некоторое время использования сообщение
    Script Expired
    помогите пожалста заранее спасибо
    Hoodognik@vtomske.ru

Комментарии закрыты