Сегодня я продолжу рассказывать о плагине jqGrid и покажу еще один пример его использования. Если не ошибаюсь, это уже 5-ый пост об этом плагине, поэтому я не буду останавливаться на его установке и настройке. Лучше приведу ссылки на предыдущие части: 1) Query Grid Plugin – "продвинутое" решение для создания таблиц 2) jqGrid: редактирование табличных данных с помощью inline редакторов 3) jqGrid – создание дополнительных кнопок 4) jqGrid – поиск данных Но для тех, кто их не читал, кратко поясню, о чем вообще речь. jqGrid – это плагин для библиотеки jQuery, предназначенный для работы с табличными данными. Он поддерживает кучу полезных возможностей вроде разбивки данных на страницы, поиска, добавления, удаления, редактирования записей и т. п. Естественно, у плагина очень много настроек и вариантов использования, но это не означает, что их хватит на все случаи жизни Например, раньше я рассказывал об использовании встроенной формы поиска jqGrid. Но иногда удобнее использовать отдельную форму, содержащую поля с автозавершением. Под ними по мере набора слова будут появляться варианты, а когда посетитель выберет один из них, то автоматически обновиться таблица с данными. Как это работает, вы можете посмотреть на демо-страничке либо скачать архив с примером и установить его на своем сервере Реализовать такую систему не сложно. Потребуются: 1) Библиотека jQuery. 2) Плагин jqGrid. 3) Плагин для создания поля с автозаполением. Я выбрал Ajax AutoComplete for jQuery. Теперь рассмотрим сам пример. 1) Клиентская часть. Тут нам нужно создать только страничку с таблицей и формой, которая содержит поле с автозаполнением (index. html).
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www. w3.org/TR/xhtml11/DTD/xhtml11.dtd”> <html xmlns=”http://www. w3.org/1999/xhtml” xml:lang=”en”> <head> <title>jqGrid + Autocomplete</title> <meta http-equiv=”content-type” content=”text/html;charset=utf-8″ /> <meta http-equiv=”Content-Style-Type” content=”text/css” /> <link rel=”stylesheet” type=”text/css” media=”screen” href=”css/reset. css” /> <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/styles. css” /> </head> <body> <div id=”container”> <h1>jqGrid + Autocomplete</h1> <table id=”list”></table> <div id=”pager”></div> <form action=”#” method=”post” id=”autocomplete_form”> <p> <label for=”city_field”>Название города</label> <input type=”text” id=”city_field” name=”city_field” size=”20″ /> </p> </form> … </div> </body> </html> * This source code was highlighted with Source Code Highlighter.
* This source code was highlighted with Source Code Highlighter. 2) Подключение и настройка плагинов. Этот код добавляем в конец файла index. html перед закрывающим тегом body.
<script src=”js/jquery-1.3.2.min. js” type=”text/javascript”></script> <script src=”js/jquery-ui-1.7.2.custom. min. js” type=”text/javascript”></script> <script src=”js/i18n/grid. locale-ru. js” type=”text/javascript”></script> <script src=”js/jquery. jqGrid. min. js” type=”text/javascript”></script> <script src=”js/jquery. autocomplete-min. js” type=”text/javascript”></script> <script type=”text/javascript”> $(function() { //настройка плагина jqGrid jQuery(“#list”).jqGrid({ url:’getdata. php’, datatype: ‘json’, mtype: ‘POST’, colNames:['Город','Страна'], colModel :[ {name:'city', index:'city', width:350}, {name:'country', index:'country', width:350} ], pager: ‘#pager’, rowNum:10, rowList:[10,20,30], sortname: ‘country’, sortorder: ‘desc’, viewrecords: true, caption: ‘Города Украины и России’ }).navGrid(‘#pager’, {edit:false, add:false, del:false, refresh:true, search:false}); //эта функция добавляет GET параметр в запрос на получение //данных для таблицы и обновляет её function updateTable(value) { jQuery(“#list”) .setGridParam({url:”getdata. php? sel_city=”+value, page:1}) .trigger(“reloadGrid”); } //настройка плагина Autocomplete //при возникновении события onSelect вызываем функцию updateTable $(‘#city_field’).autocomplete({ serviceUrl:’search. php’, maxHeight:150, onSelect: function(value) { updateTable(value); } }); //этот обработчик используется если посетитель ввел название города //и нажал Enter $(‘#autocomplete_form’).submit(function() { updateTable($(‘#city_field’).val()); return false; }); }); </script> * This source code was highlighted with Source Code Highlighter.
Для демонстрационных целей я использовал урезанную базу данных городов России и Украины, поэтому таблица содержит 2 поля: название города и название страны. На настройках отображения полей и таблицы я останавливаться не буду, т. к. уже об этом рассказывал. Тут гораздо интереснее другой момент – источники данных. И для поля, и для таблицы данные приходят в JSON формате, но для таблицы их формирует скрипт getdata. php, а для поля – search. php. Почему используются разные скрипты? Дело в том, что для плагина автозаполнения нужно меньше данных (только название города), чем для таблицы, и их структура отличается, а вводить какие-нибудь специальные параметры в запрос мне показалось не самым лучшим решением. 3) Связываем плагины между собой. Тут нам нужно чтобы при выборе посетителем города из списка произошло обновление данных в таблице.
Для этого мы в обработчик события onSelect (строки 40-42) добавили вызов функции updateTable и передали ей название города. Теперь нам нужно обновить таблицу, но при этом необходимо как-то указать, что мы хотим получить данные только для выбранного города. Т. к. таблица с данными формируется серверным php скриптом, то нам нужно создать дополнительный параметр и добавить его к запросу. Для этого с помощью метода setGridParam изменяем параметр url на getdata. php? sel_city=”+value т. е. мы добавили GET параметр sel_city. Затем вызываем метод trigger(“reloadGrid”), который запускает обновление таблицы. Еще я добавил вызов функции updateTable в обработчик отправки формы (строки 47-50). На случай если пользователь введет название города и нажмет Enter. 4) Создаем серверные скрипты. Для автозаполнения (search. php)
<?php require_once(‘dbdata. php’); try { //читаем параметры $s_query = $_GET['query']; //подключаемся к базе $dbh = new PDO(‘mysql:host=’.$dbHost.’;dbname=’.$dbName, $dbUser, $dbPass); //указываем, что нужно использовать utf8 $dbh->exec(‘SET CHARACTER SET utf8′); $stmt = $dbh->prepare(‘SELECT city FROM cities WHERE city LIKE :query’); $search = $s_query.’%'; $stmt->bindParam(‘:query’, $search); $stmt->execute(); $i=0; $response->query = $s_query; $response->suggestions = array(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $response->suggestions[]=$row['city']; } echo json_encode($response); } catch (PDOException $e) { echo ‘Database error: ‘.$e->getMessage(); } // end of search. php * This source code was highlighted with Source Code Highlighter.
Тут, набранные пользователем буквы мы получаем в параметре $_GET['query']. После этого выполняется один запрос к базе данных (строки 13-16), который находит список всех городов, начинающихся с этих букв. Затем мы формируем массив с ответом (строки 19-23) и отправляем его браузеру. Примечание. Структура массива описана в документации к плагину, вам нужно только ее соблюдать. Скрипт для заплнения таблицы (getdata. php).
<?php require_once(‘dbdata. php’); try { //читаем параметры $curPage = $_POST['page']; $rowsPerPage = $_POST['rows']; $sortingField = $_POST['sidx']; $sortingOrder = $_POST['sord']; $selCity = null; if (isset($_GET['sel_city'])) { $selCity = $_GET['sel_city']; } //подключаемся к базе $dbh = new PDO(‘mysql:host=’.$dbHost.’;dbname=’.$dbName, $dbUser, $dbPass); //указываем, что нужно использовать utf8 $dbh->exec(‘SET CHARACTER SET utf8′); //определяем количество записей в таблице if (null === $selCity) { $rows = $dbh->query(‘SELECT COUNT(id) AS count FROM cities’); } else { $rows = $dbh->query(‘SELECT COUNT(id) AS count FROM cities WHERE city=’.$dbh->quote($selCity)); } $totalRows = $rows->fetch(PDO::FETCH_ASSOC); $firstRowIndex = $curPage * $rowsPerPage – $rowsPerPage; //получаем список городов из базы if (null === $selCity) { $res = $dbh->query(‘SELECT * FROM cities ORDER BY ‘.$sortingField.’ ‘.$sortingOrder.’ LIMIT ‘.$firstRowIndex.’, ‘.$rowsPerPage); } else { $res = $dbh->query(‘SELECT * FROM cities WHERE city=’.$dbh->quote($selCity).’ ORDER BY ‘.$sortingField.’ ‘.$sortingOrder.’ LIMIT ‘.$firstRowIndex.’, ‘.$rowsPerPage); } //сохраняем номер текущей страницы, общее количество страниц и общее количество записей $response->page = $curPage; $response->total = ceil($totalRows['count'] / $rowsPerPage); $response->records = $totalRows['count']; $i=0; while($row = $res->fetch(PDO::FETCH_ASSOC)) { $response->rows[$i]['id']=$row['id']; $response->rows[$i]['cell']=array($row['city'], $row['country']); $i++; } echo json_encode($response); } catch (PDOException $e) { echo ‘Database error: ‘.$e->getMessage(); } // end of getdata. php * This source code was highlighted with Source Code Highlighter.
Тут код выглядит немного сложнее, но это только из-за использования пагинации (разбивки на страницы). На самом деле большую его часть я просто скопировал из документации к jqGrid (к тому же, он уже обсуждался). Обратить внимание нужно на обработку параметра sel_city (строки 12, 22 и 31). Если этот параметр получен, то в запрос на поиск данных мы добавляем условие WHERE city=…, если нет – берем из базы все города подряд. Я надеюсь, что у вас не возникнет проблем с этим примером. Идея ведь достаточно простая: добавить параметр с нужными данными к запросу и обработать его в серверном скрипте. Инструкции по установке и настройке примера есть в архиве. И, конечно, я буду рад услышать ваше мнение UPD 21.06.2010 В этом примере обнаружилась недоработка. Оказалось, что IE не хочет передавать название города в UTF-8 (название вставляется в URL, т. е. на сервер приходит в GET параметре).
Для решения необходимо перед отправкой закодировать название города с помощью encodeURIComponent (в браузере) и раскодировать с помощью rawurldecode (на сервере). Интересно почитать Несколько способов о том как заработать студенту в наше время. Руководителям: оказание услуг бухучета позволяет сэкономить на штатном бухгалтере