AJAX. jQuery. Использование jqGrid.

24.01.2020

jqGrid — один из компонентов jQuery часто применяемый в различных информационных системах, построеных на использовании табличной информации. При этом jqGrid не просто таблица, а таблица с возможностью динамического обновления данных посредством асинхронного javascript, что очень удобно при работе с базой данных. В основном jqGrid используется при связке с MySQL, но его можно с легкостью применять и для связки с другими БД.
Визуально jqGrid выглядит так:

jqgrid

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

<script type="text/javascript" src="js/jquery-1.4.2.min.js"</script>
<script type="text/javascript" src="js/jquery-ui.js"</script>
<script type="text/javascript" src="js/i18n/grid.locale-ru.js"</script>
<script type="text/javascript" src="js/jquery.jqGrid.min.js"</script>
<script type="text/javascript" src="js/jqDnR.js"</script>
<script type="text/javascript" src="js/jquery.maskedinput.js"</script>
<script type="text/javascript" src="js/grid.inlinedit.js"</script>
<script type="text/javascript" src="js/jquery.ui.datepicker.js"</script>
<head>
 	<link rel="stylesheet" type="text/css" media="screen" href="css/smoothness/jquery-ui-1.7.2.custom.css" />
 	<link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" />
 	<link rel="stylesheet" type="text/css" media="screen" href="css/datePicker.css" />
</head>

Описание на все эти скрипты Вы с легкостью найдете в сети, по этому не буду заострять на них внимание.
Да, здесь Вы не видите дополнительных мета-тегов, титула страницы и других не обязательных атрибутов, поскольку в моем случаее это страница во фрейме.
Таблицы jqGrid могут быть как самостоятельными объектами, так и зависимыми.
В данной статье будет рассмотрен jqGrid как самостоятельный объект, а как их (jqGrid) связывать между собой,- покажу Вам в другой раз.
Я не объявляю на такой странице теги , — во фрейме они бессмысленны. Посмотрите как выглядит приведенная на картинке выше таблица в исходном коде. Да,- по сути она формируется через javascript. Будем рассматривать код частями, т.к. объем его не маленький.

Часть первая:

<table id="list5_d"</table>
<div id="pager5_d"</div>
<script type="text/javascript">
jQuery(document).ready(function(){
var lastsel;
jQuery("#list5_d").jqGrid({
url:'basepkz/getdata_pkz.php',
datatype: 'json',
mtype: 'POST',
hiddengrid: false,
colNames:['id','Тип рельса','Длина рельса,(м)','Завод','Год прокатки','
№ плавки','Тоннаж (млн.т.брт.)','Группа  годности','Бок. износ (мм)','Верт. износ (мм)','Дата укладки в ПКЗ','Дата НК','Номер средства НК'],

Эта чась кода заканчивается зяпятой — все верно, ошибки нет, поскольку последует продолжение, но сначала давайте разберемся со смыслом показанного кода. Он взят из живой системы, а значит 100% рабочий.
В первых двух стоках обозначены, кажем так, координаты объекта, для того чтобы скрипт знал в какой области ему выполняться. Дальше пошел уже AJAX.
Прежде всего я задал переменную lastsel — в нее будет помещаться id записи в БД отображаемой в гриде.
Далее url — это путь до php_скрипта,который делает запрос к базе и формирует данные для этой таблицы в формате JSON, который и объявлен далее в параметре datatype. mtype — это способ получения информации из файла getdata_pkz.php.
hiddengrid — отображать грид свернутым или нет.
colNames — имена (заголовки) столбцов грида.
Далее каждому из столбцов нужно указать параметры отображения, возможность поиска данных по каждому из столбцов, параметры редактирования и возможные пороговые значения при редактировании. Ниже параметры некоторых столбцов нашей таблицы.

colModel :[
{name:'pk', index:'pk', width:69, align:'center',hidden:true,editable:true,search:false}
,{name:'tipr', index:'tipr', width:69, align:'center',editable:true,edittype:"select",
editoptions: {dataUrl:'basepd/seltipr.php'},
searchoptions:{sopt:['eq','ne','bw','cn']},
formoptions:{rowpos:2, colpos:1,label:'Тип рельса'}}
,{name:'dlr', index:'dlr', width:70, align:'center',editable:true,search:false,
editoptions:{size:7},
editrules:{number:true,minValue:1,maxValue:25},
formoptions:{rowpos:2, colpos:2,label:'Длина рельса (м)'}}
// пропущено....
,{name:'god', index:'god', width:82, align:'center',editable:true,
editoptions:{size:7,  dataInit:function(elem3){
$(elem3).mask("99.9999");
}
},
searchoptions:{sopt:['cn']},
formoptions:{rowpos:3, colpos:2,label:'Год прокатки'}}
// пропущено....
,{name:'dataukl', index:'dataukl', width:95, align:'center',search:false,editable:true,
editoptions:{size:7,   dataInit:function(elem){
$(elem).datepicker({dateFormat:'dd.mm.yy'});
}
// пропущено..
} ],

Часть кода я пропустил намеренно, поскольку он по большей части однотипен и займет много места…
Рассмотрим colModel чуть подробнее.
name — это имя поля в котором возвращается значения из уже указанного ранее getdata_pkz.php. index — для удобства равен значению name, используется для сортировки.
editable — указывает является ли данное поле доступным для редактирования.
hidden — устанавливает видимость поля в гриде
search — можно ли выполнять поиск встроенными средствами по этому полю
edittype — способ отображения на форме редактирования, тут может быть и комбобокс с набором данных и просто текстовый редактор, и другой элемент (например календарь). editoptions — если это бокс с набором данных, то путь к набору, если текст — ограничения по длине или иное, если календарь, — то соответсвенно его вызов, ну и тут же может быть ввод данных по маске (все примеры есть в коде).
Для маски применятся вызов функции dataInit, в которой и описываются ограничения ввода, аналогично и для календарика.
Следует так же описать параметр formoptions — в нем описываются настройки формы редактирования данных.
Например такое описание : {rowpos:3, colpos:2,label:’Год прокатки’}, означает что на форме редактирования этот элемент будет находиться в третьей строке второго столбца. Вид формы редактирования:

edit form jqgrid

Параметры колонок и организации формы редактирования рассмотрели. Продолжим описание построения грида на web-странице.

pager: jQuery('#pager5_d'),
rowNum:20,
rowList:[20,50,100],
sortname: 'pk',
sortorder: "asc",
viewrecords: true,
multiselect: false,
height: "auto",
shrinkToFit: false,
rownumbers: true,
caption: 'Сведения о наличии рельсов в ПКЗ',

Это так называемый пейджер. Его параметры:
rowNum — сколько строк показывать изначально.
rowList — выбор отображения количества строк на странице.
sortname — поле сортировки данных по умолчанию.
sortorder — способ сортировки.
viewrecords — отображать или нет записи.
multiselect — разрешение на множественный выбор строк.
height — тут все понятно.
shrinkToFit — автовыравнивание по смыслу, но ведет себя не всегда стандартно. rownumbers — нумерация строк.
caption — заголовок грида.
Но и это еще не все 🙂
Конечно на данном тапе со структурой грида покончено и он готов к наполнению данными, но ведь требуется еще и возможность редактирования информации, добавления и удаления записей, а так же иных пользовательских операций.

jqgrid-del

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

onSelectRow: function(pk) {
if(pk &amp;amp;&amp;amp; pk !== lastsel2) {
$('#list5_d').jqGrid('restoreRow', lastsel);
$('#list5_d').jqGrid('editRow', pk, true);
lastsel = pk;
//получили порядковый номер записи выбранной в гриде
}}
, editurl: 'basepkz/edit.php'
}).navGrid('#pager5_d',{edit:true,add:true,del:true,search:true,excel:true},
{height:475,width:570,closeOnEscape:true, closeAfterEdit:true, editData: {op: "edit"}}, //   edit
{height:475,width:570,closeOnEscape:true, closeAfterEdit:true, editData: {op: "add"}}, //   add
{width:290,
url: 'basepkz/delr.php',
reloadAfterSubmit:false,
delData: {
pk: function () {
var pk_row = $('#list5_d').getGridParam('selrow');
var value = $('#list5_d').getCell(pk_row,'pk');
return value;  }
},mtype: 'POST'},  // delete
{closeOnEscape:true, multipleSearch:false, closeAfterSearch:true}, // search options
{} /* view parameters*/
).navButtonAdd('#pager5_d',{ id:"copy",caption:"",title:"Дублировать запись", onClickButton:
function(copy){
var gr = jQuery('#list5_d').getGridParam('selrow');
if( gr != null ) {jQuery("#list5_d").editGridRow(gr,{
closeAfterEdit: true,
height:700,
width:370,
editCaption:"Клонировать выбранную запись",
url: 'basepkz/edit.php',
editData: {op: "add"}
} )
}else{
alert('Не выбрана запись для копирования!');
};
}, position:"last"})
.navButtonAdd('#pager5_d',{ id:"send",caption:"",title:"Передать рельс",buttonicon:"ui-icon-extlink",
onClickButton:
function(){
var selstr = jQuery('#list5_d').getGridParam('selrow');
var pkstr = jQuery('#list5_d').getCell(selstr,'pk');
jQuery('#list5_d').trigger("reloadGrid");
}else{
alert('Не выбран рельс для передачи!');
}
}, position:"last"})
.navButtonAdd('#pager5_d',{ id:"xls",caption:"",title:"Передать в Excel",buttonicon:"ui-icon-print",
onClickButton:
function(){window.open("basepkz/export.php?pd=169&amp;amp;pkz="+key);
}, position:"last"});
});
&amp;lt;/script&amp;gt;

Используя параметр navGrid мы говорим гриду что у него есть кнопки навигации и он позволяет добавить стандартный набор кнопок, а вот для того чтобы добавить дополнительные кнопки, — используется оператор navButtonAdd. Вот теперь jqGrid почти готов к полноценной работе. Почему «почти» ? Потому что необходимо еще подключить php-скрипты для форм редактирования, а так же скрипт подачи информации в грид. Последний рассмотрим, а остальное на самостоятельное изучение. Вы всегда можете задать вопрос если не разберетесь самостоятельно.
Вот и тот самый скрипт, который отдает информацию в грид.

//указываем, мы хотим использовать utf8
$dbh-&amp;gt;exec('SET CHARACTER SET utf-8');
$page = $_POST['page']; // текущая страница
$limit = $_POST['rows']; // количество строк отображаемое в гриде
$sidx = $_POST['sidx']; // сортировка по полю грида
$sord = $_POST['sord']; // get the direction
if(!$sidx) $sidx =1;
//------- поиск ------------- этот блок закомментирован, т.к. я не использовал встроенный поиск
/*if($_search){
if (isset($_POST['filters'])) $filters = $_POST['filters'];// Фильтры для поиска
if (isset($_POST['searchField'])) $searchField = $_POST['searchField']; // Фильтр по одному полю (имя)
if (isset($_POST['searchOper'])) $searchOper = $_POST['searchOper']; // Фильтр по одному полю (операция)
if (isset($_POST['searchString'])) $searchString = $_POST['searchString']; // Фильтр по одному полю (значение)
$searchString = generateSearchString($filters, $searchField, $searchOper, $searchString);
}*/
// --------------------------
$dbhost='localhost';
$dbuser='dbuser';
$dbpassword='';
$database='dbname';
// connect to the database
$db = mysql_connect($dbhost, $dbuser, $dbpassword)
or die("Ошибка соединения: " . mysql_error());

mysql_select_db($database) or die("Ошибка соединения с базой данных");
$result = mysql_query('SELECT COUNT(pk) AS count FROM view_bpkz  WHERE key_pd= '.$kpd.' and key_pkz=' .$pkzbaza.'');
$row = mysql_fetch_array($result,MYSQL_ASSOC);
$count = $row['count'];
if( $count == 0 )  {
$responce-&amp;gt;rows[$i]['cell']=array(0,'','','','','','','','','','','','','','','','',''); // по количеству полей, - не обязательно, но иначе у меня выходила ошибка
echo json_encode($responce);
}else{
if( $count &amp;gt;0 )  {
$total_pages = ceil($count/$limit);
} else {
$total_pages = 0;
}
if ($page &amp;gt; $total_pages) $page=$total_pages;
$start = $limit*$page - $limit; // do not put $limit*($page - 1) ...если нет значений то старт будет = 0
// запрос к БД на получение необходимых значений, у каждого он свой..
$SQL = "SELECT *, DATE_FORMAT(dataukl,'%d.%m.%Y') as dataukl,DATE_FORMAT(datank,'%d.%m.%Y') as datank FROM view_bpkz WHERE key_pd= $kpd and key_pkz= $pkzbaza  ORDER BY $sidx $sord LIMIT $start , $limit";

$result = mysql_query( $SQL ) or die("Ошибка выполнения запроса.".mysql_error());

$responce-&amp;gt;page = $page;
$responce-&amp;gt;total = $total_pages;
$responce-&amp;gt;records = $count;
$i=0;
while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {
// помещаем в ячейки строки значения массива..
$responce-&amp;gt;rows[$i]['cell']=array($row[pk],$row[tipr],$row[dlr],$row[zav],$row[god],$row[plavka],$row[tonn],$row[grg],$row[bi],$row[vi],$row[dataukl],$row[datank]);
$i++;
// переходим к следующей строке массива
}
echo json_encode($responce); // вывод данных для jqGrid
}

Надеюсь особых сложностей не возникло.
Конечно это далеко не все возможности jqGrid и полный перечень Вы можете посмотреть на сайте разработчиков jQuery.

PS: Буду благодарен за LIKE кнопкой соцсети справа от записи.

Комментарии

6 комментариев к записи “AJAX. jQuery. Использование jqGrid.”
  1. sanchespb:

    код edit.php выложите.

    • Maks:

      edit.php обычный скрипт выполняющий удаление или редактирование записи…
      в данном случае файлу edit.php передается параметр на редактирование или удаление хаписи. Дальнейшая обработка должна быть и так понятна. Если все же есть необходимость — выложу код

  2. yakov:

    Выложи ссылку на полный исходник для обучения

Оставить комментарий