Сегодня я продолжу рассказывать о плагине jqGrid и покажу еще один пример его использования.
Если не ошибаюсь, это уже 5-ый пост об этом плагине, поэтому я не буду останавливаться на его установке и настройке. Лучше приведу ссылки на предыдущие части:
1) Query Grid Plugin – «продвинутое» решение для создания таблиц
2) jqGrid: редактирование табличных данных с помощью inline редакторов
3) jqGrid – создание дополнительных кнопок
Но для тех, кто их не читал, кратко поясню, о чем вообще речь.
jqGrid – это плагин для библиотеки jQuery, предназначенный для работы с табличными данными. Он поддерживает кучу полезных возможностей вроде разбивки данных на страницы, поиска, добавления, удаления, редактирования записей и т.п.
Естественно, у плагина очень много настроек и вариантов использования, но это не означает, что их хватит на все случаи жизни 😉
Например, раньше я рассказывал об использовании встроенной формы поиска jqGrid. Но иногда удобнее использовать отдельную форму, содержащую поля с автозавершением. Под ними по мере набора слова будут появляться варианты, а когда посетитель выберет один из них, то автоматически обновиться таблица с данными.
Как это работает, вы можете посмотреть на демо-страничке
Demoлибо скачать архив с примером и установить его на своем сервере
SourceРеализовать такую систему не сложно.
Потребуются:
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 (на сервере).
Интересно почитать
Несколько способов о том как заработать студенту в наше время.
Руководителям: оказание услуг бухучета позволяет сэкономить на штатном бухгалтере