На этом шаге мы рассмотрим динамическое формирование подсказок из данных, полученных с сервера.
Материал этого шага базируется на 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.