В этой статье я расскажу про создание элемента с автодополнением в форме редактирования строки jqGrid. Будет рассматриваться именно режим редактирования строки. В jqGrid есть три режима редактирования: редактирование ячейки, редактирование строки и редактирование в форме редактирования.
Краткий курс теории. Редактирование строки в jqGrid начинается с вызова метода grid.editRow(rowId, keys). При этом создаются элементы редактирования строк у которых hidden=false на основе описания в colModel. Атрибуты name созданных элементов равны атрибутам name из colModel. При сохранении значения созданных элементов управления отправляются на сервер парами name=value с добавлением id=rowid.
Чтобы создать автодополнение мы используем событие dataInit в editoptions. Туда передаётся элемент, и мы инициализируем автодополнение для него. Поскольку редактирование вызвано для столбца с ФИО, то столбец с personId этого ФИО мы должны обновлять сами.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<!DOCTYPE HTML> <html> <head> <title>jqGrid inline autocomplete</title> <META http-equiv=Content-Type content="text/html; charset=utf-8"> <!-- JQuery CSS --> <link rel="stylesheet" href="../../../jquery-ui-themes/1.11.4/themes/redmond/jquery-ui.min.css" type="text/css" /> <!-- jqGrid CSS --> <link rel="stylesheet" href="../../../jqgrid/5.0.0/css/ui.jqgrid.css" type="text/css" /> <!-- JQuery --> <script src="../../../jquery/2.1.3/jquery-2.1.3.js"></script> <script src="../../../jquery/2.1.3/jquery.json.js"></script> <!-- The JQuery UI code --> <script type="text/javascript" src="../../../jquery-ui/1.11.4/jquery-ui.min.js" > </script> <!-- The jqGrid language file code--> <script type="text/javascript" src="../../../jqgrid/5.0.0/js/i18n/grid.locale-ru.js" > </script> <!-- The atual jqGrid code --> <script type="text/javascript" src="../../../jqgrid/5.0.0/js/jquery.jqGrid.min.js" > </script> <script type="text/javascript" src="inlineautocomplete.js"> </script> </head> <body> <a href="https://urvanov.ru/2015/07/18/jqgrid-inline-edit-autocomplete/"> Статья с описанием примера jqGrid inline autocomplete</a> <p> Начните редактировать значение в какой-нибудь ячейке столбца ФИО, чтобы увидеть автодополнение. </p> <!-- Редактирование в строке автодополнение --> <table id="staffListsGrid"> </table> <div id="staffListsGridPager"></div> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
//////////////////////////////////////////////////////////////////////////////// // inlineautocomplete.js // https://urvanov.ru // //////////////////////////////////////////////////////////////////////////////// (function() { function onReady() { // Данные в выбранной строке. var selectedRowData = null; // Новые данные в выбранной строке var newRowData = null; // id выбранной строки var lastselId = null; // Инициализация jqGrid $("#staffListsGrid").jqGrid({ regional : "ru", // Русская локаль forceRegional : true, url : "data.php", // Данные берём с data.php mtype : "POST", datatype : "json", editurl : 'save.php', // URL для сохранения изменений. // Будет вызываться перед отправкой данных в строке на сервер. // Преобразуем объект в строку JSON serializeRowData : function(postData) { return JSON.stringify(postData); }, ajaxRowOptions : { contentType : 'application/json' }, // При смене выделенной строки сохраняем изменения. onSelectRow: function(id){ if(lastselId && id!==lastselId){ saveCurrentRow(); } calcId = $("#calcSelect").val(); var grid = $("#staffListsGrid"); selectedRowData = grid.jqGrid("getRowData", id); newRowData = grid.jqGrid("getRowData", id); grid.editRow(id, false); lastselId=id; }, colModel : [ { label : 'ID', name : 'id', key : true, editable : false, hidden : true, sortable : false }, { label : 'Описание', name : 'descr', width : 200, editable : false, sortable : true, sorttype : 'text' },{ label : 'personId', name : 'personId', editable : false, hidden : true, sortable : false }, { label : 'ФИО', name : 'personName', width : 300, editable : true, editoptions : { dataInit : function (el) { // Основная магия здесь. // Инициализируем jQuery autocomplete. $(el).autocomplete( { source : function (request, response) { $.ajax({ type : "POST", // Адрес для запроса на список подходящих // значений для автодополнения url : 'autocomplete.php', // Параметры. data : { term : request.term, calcId : calcId, personId : selectedRowData.personId }, success : function(ret, textStatus, jqXhr) { // Возвращаем полученные данные. response(ret); }, error : function (jqXhr, textStatus, errorThrown) { if (console) console.log("Autocomplete failed."); } }); }, select : function (event, ui) { // Сохраняем ID выбранной записи. newRowData.personId = ui.item.value; // Подставляем надпись в сам элемент редактирования. $(el).val(ui.item.label); // Останавливаем дальнейшую обработку события. return false; }, open : function ( event, ui ) { $(".ui-autocomplete").css("zIndex", 10000); } }); $(el).on("keydown", function (event) { // Сохраняем строку при нажатии ВВОД. var code = event.which; if(code==13) event.preventDefault(); if(code==32||code==13||code==188||code==186) { saveCurrentRow(); } }); } }, sortable : true, sorttype : 'text' } ], viewrecords : true, width : 600, height : 'auto', rowNum : 20, pager : "#staffListsGridPager" }); // Сохранение текущей редактируемой строки. function saveCurrentRow() { var grid = $("#staffListsGrid"); // jqGrid при editRow создаёт элементы редактирования по схеме // rowid_columnName, где rowid - id строки, // columnName - name из colModel. var personNameEditElId='#'+selectedRowData.id+"_personName"; if (!$(personNameEditElId).val()) { // Если поле ввода ФИО очищено, то очищаем первичный ключ. newRowData.personId = null; } else if (newRowData.personId == selectedRowData.personId) { // Восстанавливаем прежнее ФИО, если ничего не выбрано. $(personNameEditElId).val(selectedRowData.personName); } grid.jqGrid("setRowData", lastselId, {personId : newRowData.personId}); grid.saveRow(lastselId, null, null, { personId : newRowData.personId }); } var grid = $("#staffListsGrid"); grid.trigger("reloadGrid"); } $(document).ready(onReady); })(); |
Также создадим PHP-скрипт, которые будет возвращать небольшой набор данных для нашего примера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php // Данные для примера // data.php // https://urvanov.ru session_start(); if (!isset($_SESSION['jqgridautocompletedata'])) { $d = array( array('id'=>'1','descr' =>'Первая строка', 'personId' => '1', 'personName' => 'Иванов Алексей'), array('id'=>'2', 'descr' =>'Вторая строка', 'personId' => null, 'personName' => null), array('id'=>'3', 'descr' =>'Третья строка', 'personId' => null, 'personName' => null) ); $_SESSION['jqgridautocompletedata']= $d; } else { $d = $_SESSION['jqgridautocompletedata']; } header('Content-Type=> application/json;charset=UTF-8'); print json_encode($d); ?> |
И небольшой скрипт, который будет сохранять наши изменения тестовых данных в сессии.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php // Сохранение данных в сессии // save.php // https://urvanov.ru session_start(); $json = file_get_contents('php://input'); $obj = json_decode($json); $_SESSION['jqgridautocompletedata'] [intval($obj->id)-1]['personId'] = $obj->personId; $_SESSION['jqgridautocompletedata'] [intval($obj->id)-1]['personName'] = $obj->personName; print json_encode($_SESSION['jqgridautocompletedata']); ?> |
Скрипт поиска данных для автодополнения получает параметр term, содержащий строку поиска:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?php // Автодополнение // autocomplete.php // https://urvanov.ru session_start(); $d=array(); // фраза, по которой ищем. $term = $_REQUEST['term']; // изначальный массив $autocompletedata = array(array('label'=>'Иванов Василий', 'value' =>'1'), array('label' => 'Смирнов Дмитрий', 'value' => '2'), array('label' => 'Смирнов Алексей', 'value' => '3'), array('label' => 'Алексеев Дмитрий', 'value' => '4'), array('label' => 'Алексеев Иван', 'value' => '5'), array('label' => 'Алексеев Матвей', 'value' => '6')); // фильтруем данные foreach ($autocompletedata as $item) { // ищем подстроку регистронезависимо. if (strpos(mb_convert_case($item['label'], MB_CASE_LOWER,'UTF-8'), mb_convert_case($term, MB_CASE_LOWER, 'UTF-8')) !== false) { // если подходит, то включаем в результат. array_push($d, $item); } } header('Content-Type: application/json;charset=UTF-8'); // возвращаем JSON с данными. print json_encode($d); ?> |
Тут надо сказать, что меня немного удивило то, что PHP не может сразу работать со строками в кодировке UTF-8. Для них нужно использовать специальные функции.
Ссылки:
https://urvanov.ru/projects/jqgrid-examples/5.0.0/inline-autocomplete/
— получившаяся таблица с автодополнением
http://www.trirand.com/jqgridwiki/doku.php — документация на jqGrid
Документация jqGrid на русском — документация jqGrid на русском
http://api.jqueryui.com/autocomplete/ — jQueryUI autocomplete Widget
Отличная статья. Спасибо!
Огромное спасибо. Сам день бы потратил пока понял бы как jqgrid с autocomplete подружить. От себя добавлю — Для jquery 11:
$(el).autocomplete( {
source : function (request, response) {
$.ajax({
dataType: «json»
})
}
})
Иначе не работает.