На этом шаге мы рассмотрим динамическое формирование подсказок из данных, полученных с сервера.
Материал этого шага базируется на http://www.linkexchanger.su/2011/700.html.
На прошлых шагах мы рассмотрели, как настраивать виджет и управлять им, но пока мы использовали исключительно локальные данные для формирования списка подсказок. В реальной работе наверняка потребуется формировать подсказки из данных, хранящихся на своем сервере, а может быть и вообще не на своем.
Опция source, которая, напомню, является обязательной и определяет источник данных, может принимать также строку, где содержится url, к которому следует отправлять запрос. А еще в source можно определить свою функцию, которая будет делать, то что надо именно разработчику. Вот этот, пожалуй самый гибкий способ мы и разберем. Попробуем получить в виде списка подсказок какие-либо данные с сервера geonames.org.
Сначала приведем рабочий код, потом объясним, как и что работает.
Сначала - разметка HTML-документа:
. . . . <head> <meta http-equiv="Content-Type" content="text/html; charset=win-1251"/> <style type="text/css"> .ui-autocomplete-loading { background: #FFF url('css/ui-lightness/images/ui-anim_basic_16x16.gif') right center no-repeat; } #city { width: 25em; } #log { height: 200px; width: 600px; overflow: auto; } </style> <title>jQuery UI</title> <link href="css/ui-lightness/jquery-ui-1.10.0.custom.css" rel="stylesheet" /> <script src="js/jquery-1.9.0.js" type="text/javascript"></script> <script src="js/jquery-ui-1.10.0.custom.js" type="text/javascript"></script> <script src="ui235_1.js" type="text/javascript"></script> </head> <body> <div class="ui-widget"> <label for="city">Город: </label><input id="city" /><br /> <span style="font-size:.8em;">Поддерживается <a href="http://geonames.org">geonames.org</a></span> </div> <div id="log" class="ui-widget ui-widget-content"></div> </body> . . . .
Сначала смотрим на HTML-разметку. В первом элементе div нас интересует только элемент input с идентификатором city. Сюда будем вводить начальные буквы (на латинице) населенного пункта, информацию о котором мы хотели бы получить. Элемент div с идентификатором log используем для занесения в него полученной информации. Отметим, что стиль оформления элементов определен в заголовке документа.
Теперь - текст скрипта:
$(document).ready(function() { $("#city").autocomplete({ source: function(request,response) { $.ajax({ url: "http://ws.geonames.org/searchJSON", dataType: "jsonp", data: { featureClass: "P", style: "full", maxRows: 12, name_startsWith: request.term }, success: function(data) { response($.map(data.geonames, function(item) { return { label: item.name + ", " + item.countryName, value: item.name + " (" + item.countryName + ")" + " [" + item.lat + ", " + item.lng + "]" } })); } }); }, minLength: 3, select: function(event,ui) { $("<p/>").text(ui.item ? ui.item.value : "Ничего не выбрано!") .prependTo("#log"); $("#log").attr("scrollTop", 0); } }); });
Если смотреть JavaScript-код, то увидим, что объект с настройками содержит три свойства - обязательное свойство source, а также свойства minLength и select.
Мы займемся рассмотрением только свойства source, где можно написать свою функцию. Эта функция принимает два аргумента. Первый аргумент - request - объект, содержащий единственное свойство term, в котором хранится строка, введенная пользователем в поле ввода. Второй аргумент - response - функция, с помощью которой будет обрабатываться полученный ответ.
Внутри функции, определенной в свойстве source, мы имеем практически неограниченную свободу действий. Поэтому пишем там ajax-запрос к url http://ws.geonames.org/searchJSON, в опции dataType указываем, что в ответе ожидаем получить данные в формате JSON. В опции data определяем объект с параметрами запроса, который будет отправляться на указанный url (почему параметры именно такие - надо смотреть документацию по API на сервере geonames.org). В последнем параметре передаем request.term - то, что ввел пользователь.
В следующей опции ajax-запроса - опции success, вызываем функцию обработки ответа response. В аргументе, который мы передаем этой функции, мы можем обрабатывать данные, полученные в ответе сервера так, как нам будет угодно. Мы используем метод $.map чтобы применить некоторую функцию к каждому элементу объекта, переданному в первом аргументе. Внутри функции мы можем обращаться к свойствам объекта - item.countryName, item.lng, item.lat (почему свойства именно такие - см. документацию по API, которую предоставляет веб-сервис). Функция, которую мы написали, для каждого элемента возвращает объект, содержащий два свойствами, которые мы определили самостоятельно, используя полученные данные. Из получившегося массива таких объектов и строится список подсказок.
Результат работы скрипта приведен на рисунке 1.
Рис.1. Результат работы скрипта
На следующем шаге мы рассмотрим виджет Validation.