Дискретные подсказки для адреса
В основной статье про подсказки для почтовых адресов, которую можно посмотреть здесь, мы рассказали, как с помощью Ахантера сделать быстрый и удобный ввод почтового адреса одной строкой в одном поле формы.
В противовес этому, дискретный ввод подразумевает, что почтовый адрес вводится по частям, так что каждой части адреса соответствует отдельное поле формы. Подсказки в этом случае формируются для каждого такого поля по отдельности, а не для всего адреса целиком. Например, можно в отдельных полях вводить название города и улицы. При использовании дискретных подсказок Ахантер будет предлагать названия городов при заполнении поля с городом. После того, как пользователь закончит вводить город и переключится на поле с улицей, Ахантер начнёт предлагать подсказки для улиц из этого города.
Хотя дискретный ввод адреса не так удобен, как ввод в одном поле, у него есть одно преимущество. Если в вашем приложении или веб-сайте пользователи чаще всего вводят адреса из одного и того же города, то для названия города можно выделить на адресной форме отдельное поле и автоматически заполнять его значением по умолчанию с названием этого наиболее популярного города. В этом случае большинству ваших пользователей нужно будет заполнять только поля с улицей, номером дома, корпусом и квартирой.
Приведенная ниже форма демонстрирует работу дискретных подсказок для почтового адреса. Для отображения подсказок достаточно начать вводить адресные данные в первом поле формы.
Здесь для отображения подсказываемых адресов используется наш JavaScript-модуль ahunter_suggest.js, скачать его можно по следующей ссылке. Модуль использует библиотеку jQuery, поэтому, чтобы запустить подсказки у вас на сайте, в дополнение к ahunter_suggest.js нужно будет установить свежую версию jQuery.
Чтобы всё это заработало, мы использовали здесь следующий JavaScript-код.
//настраиваем подсказки для ввода адреса в нескольких полях var options = { fields: [ { id: 'js-Field1', levels: ['Region','District','City','Place'] }, { id: 'js-Field2', levels: ['Site','Street'] }, { id: 'js-Field3', levels: ['House','Building','Structure'] }, { id: 'js-Field4', levels: ['Flat'] } ] }; //запускаем дискретные подсказки AhunterSuggest.Address.Discrete( options );
Детальное описание этого кода, а также описание подготовки вашего сайта к использованию подсказок приводится далее в этой статье.
В большинстве случаев для работы с подсказками бывает достаточно использовать модуль ahunter_suggest.js. Однако если вам нужно встроить подсказки в отдельное приложение, либо если у вас есть своё JavaScript решение для отображения подсказок, то для получения подсказок от Ахантера нужно будет использовать напрямую его REST API. Соответствующее описание приводится во второй части данной статьи.
Для добавления дискретных подсказок на сайт, как и в случае с обычными адресными подсказками, необходимо выполнить подготовку сайта. А именно, нужно установить jQuery, установить наш JavaScript-модуль ahunter_suggest.js, а также настроить таблицу стилей, чтобы подсказки отображались красиво.
Все эти процедуры детально описаны по следующей ссылке.
При подключении дискретных подсказок важно понимать, что полей для ввода адреса должно быть несколько, как минимум – два. Вместе с тем структура почтового адреса у Ахантера подразумевает наличие десяти адресных компонентов. Все эти десять компонентов имеют англоязычные имена, а также однобуквенные идентификаторы. Имена требуются, чтобы корректно сконфигурировать вашу адресную форму, а однобуквенные идентификаторы нужны для использования дискретных подсказок напрямую через REST API.
Чтобы эта информация всегда была под рукой, мы подготовили её в виде следующей таблицы.
Компонент адреса в Ахантере | Имя | ID | Пример |
Регион РФ | Region | r | Московская область |
Административный район | District | d | Одинцовский район |
Крупный город | City | c | город Новосибирск |
Небольшой населённый пункт | Place | p | деревня Иваново |
Территория | Site | t | территория Ленинские Горы |
Улица | Street | s | Тверская улица |
Номер дома | House | h | дом 23 |
Номер корпуса | Building | b | корп 1 |
Номер строения | Structure | u | стр 2 |
Номер квартиры или офиса | Flat | f | кв 3 |
Если каждому адресному компоненту из нашей таблицы в вашей форме будет соответствовать отдельное поле для ввода, то сама форма получится весьма громоздкой, и в большинстве случаев она будет сбивать ваших пользователей с толку. Например, не все пользователи понимают, чем населённый пункт отличается от города, или чем территория отличается от улицы.
Чтобы избежать этих проблем, дискретные подсказки позволяют объединять адресные компоненты так, чтобы несколько наших адресных компонентов можно было вводить в одно поле вашей формы. Например, можно объединить регион и административный район, чтобы пользователь вводил их в одно поле. При этом подсказки будут предлагаться только для регионов и районов.
Таким образом, при подключении дискретных подсказок вам нужно решить, сколько полей в вашей форме будет использоваться для ввода адреса. После этого нужно будет установить соответствие между вашими полями и нашими адресными компонентами, при необходимости объединяя несколько наших компонентов в одно общее поле. Это соответствие между вашими полями и нашими компонентами нужно будет правильно описать в опциях и передать их модулю ahunter_suggest.js при запуске подсказок на вашем сайте.
Для понимания этой процедуры рассмотрим следующий пример. Допустим, у вас адрес вводится в форму с четырьмя полями. Соответствующая HTML-разметка может выглядеть следующим образом.
<div> <input id="js-Field1" placeholder="Регион, район, город, нас. пункт"/> <input id="js-Field2" placeholder="Территория или улица"/> <input id="js-Field3" placeholder="Дом, корпус или строение"/> <input id="js-Field4" placeholder="Квартира"/> </div>
Согласно этой форме, мы планируем в первое поле с идентификатором js-Field1 вводить название региона, района, города и населённого пункта. Когда пользователь будет заполнять данное поле, Ахантер будет предлагать подсказки сразу для этих четырёх компонентов адреса. Например, в этом поле может быть введена такая строка Московская область, город Раменское или даже такая строка обл Астраханская, р-н Ахтубинский, г Ахтубинск, п Джелга.
Во второе поле нашей формы с идентификатором js-Field2 пользователи будут вводить названия территорий или улиц. Например, в этом поле может быть введена строка только с названием улицы - улица Тверская. Вместе с тем в этом поле может быть введена строка, содержащая одновременно и улицу, и территорию - снт СОТ Нива, ул Им. И. Гончарова (здесь указана улица в рамках территории, являющейся садоводческим товариществом Нива).
В третьем поле с идентификатором js-Field3 пользователи будут указывать одновременно номер дома, корпуса и строения. А в последнем поле с идентификатором js-Field4 – только номер квартиры.
Теперь, чтобы сообщить Ахантеру, какие подсказки он должен предлагать при заполнении этих полей, необходимо в опциях модуля явно указать связь между адресными компонентами Ахантера и вашими адресными полями. Для этого на странице с формой нужно добавить следующий код:
//настраиваем подсказки для ввода адреса в нескольких полях var options = { fields: [ { id: 'js-Field1', levels: ['Region','District','City','Place'] }, { id: 'js-Field2', levels: ['Site','Street'] }, { id: 'js-Field3', levels: ['House','Building','Structure'] }, { id: 'js-Field4', levels: ['Flat'] } ] }; //запускаем дискретные подсказки AhunterSuggest.Address.Discrete( options );
Здесь видно, что в опциях options заполняется список fields, в котором каждый элемент устанавливает связь между полем вашей адресной формы и несколькими адресными компонентами, для которых Ахантер будет предлагать подсказки. Каждый элемент массива options.fields содержит следующие два обязательных поля:
В приведённом примере видно, что при заполнении первого поля адресной формы с идентификатором js-Field1 будут предлагаться подсказки с названиями регионов (Region), районов (District), городов (City) и населённых пунктов (Place). Если пользователь начнёт вводить в это поле название улицы или номер дома, Ахантер перестанет показывать подсказки и выдаст предупреждающее сообщение. Аналогичным образом сконфигурированы остальные поля формы.
При задании списка levels важно учитывать, что в нём должны быть перечислены только соседние по нашей таблице компоненты адреса. Например, нельзя поле формы привязать к регионам (Region) и к городам (City), минуя при этом компонент с районами (District). Также нельзя один и тот же компонент адреса привязывать сразу к нескольким разным полям вашей формы.
После того, как настройки в объекте options заполнены, они передаются нашему модулю посредством вызова AhunterSuggest.Address.Discrete( options ). Этот вызов привяжет функционал дискретных подсказок к заданным в списке options.fields полям формы, так что ввод почтовых адресов в этих полях будет приводить к отображению подсказок.
В настройках options можно указывать и другие опции, которые будут влиять на поведение и внешний вид подсказок. Рассмотрим их подробнее.
Как было описано чуть выше, каждому адресному полю вашей формы в списке options.fields соответствует отдельный объект. Каждый такой объект должен иметь обязательное поле id и список levels. Кроме них в этом объекте можно указать любой из параметров, которые применяются для обычных адресных подсказок. Посмотреть эти параметры можно здесь. В дополнение к ним дискретные подсказки поддерживают следующие параметры:
Для демонстрации использования дополнительных опций рассмотрим в качестве примера следующую форму.
<div> <input id="js-Field1" placeholder="Регион, район, город, нас. пункт"/> <input id="js-Field2" placeholder="Территория или улица"/> <input id="js-Field3" placeholder="Дом"/> <input id="js-Field4" placeholder="Корпус или строение"/> <input id="js-Field5" placeholder="Квартира"/> </div>
В отличие от предыдущего примера, мы будем вводить номер корпуса и строения в отдельное поле с идентификатором js-Field4. Чтобы запустить подсказки в данной форме, добавим следующий инициализирующий код:
//настраиваем подсказки для ввода адреса в нескольких полях var options = { fields: [ { id: 'js-Field1', levels: ['Region','District','City','Place'] }, { id: 'js-Field2', levels: ['Site','Street'] }, { id: 'js-Field3', levels: ['House'] }, { id: 'js-Field4', levels: ['Building','Structure'], suggest_on_focus : true, suggest_on_empty : true, limit : 5 }, { id: 'js-Field5', levels: ['Flat'] } ] }; //запускаем дискретные подсказки AhunterSuggest.Address.Discrete( options );
Поскольку на форме появилось дополнительное поле, мы добавили соответствующий элемент в список options.fields. Этот элемент связывает поле с идентификатором js-Field4 с двумя компонентами адреса Building и Structure, которые, согласно нашей табличке, соответствуют номеру корпуса и строения. Дополнительно у данного поля мы выставили в true флаги suggest_on_focus и suggest_on_empty. Таким образом, когда пользователь просто выберет пустое поле js-Field4, он тут же получит варианты с подсказками для корпусов и строений вводимого адреса. Также, с помощью параметра limit мы уменьшили до 5 количество подсказок, предлагаемых персонально у этого поля.
Можно посмотреть, как это будет работать вживую на следующей форме. Здесь мы по умолчанию уже заполнили первые три поля, поэтому, чтобы посмотреть подсказки для строений, достаточно щёлкнуть мышкой на предпоследнем поле.
Все дополнительные параметры в options можно задавать не для каждого поля по отдельности, а сразу для всех полей формы. Например, для предыдущего примера можно сделать так:
//настраиваем подсказки для ввода адреса в нескольких полях var options = { fields: [ { id: 'js-Field1', levels: ['Region','District','City','Place'] }, { id: 'js-Field2', levels: ['Site','Street'] }, { id: 'js-Field3', levels: ['House'] }, { id: 'js-Field4', levels: ['Building','Structure'] }, { id: 'js-Field5', levels: ['Flat'] } ], suggest_on_focus : true, suggest_on_empty : true, limit : 5 }; //запускаем дискретные подсказки AhunterSuggest.Address.Discrete( options );
В данном случае флаги suggest_on_focus и suggest_on_empty, а также лимит на число показываемых подсказок limit, будут применяться ко всем полям формы, а не только для js-Field4, как это было в предыдущем примере.
Кроме этих возможностей дискретные подсказки позволяют добавить на форму отдельное поле, куда пользователь может вводить почтовый индекс. Если пользователь заполнит это поле корректным индексом, то подсказки для остальных полей формы будут ограничены адресами, индексы которых совпадают с этим индексом. Чтобы сообщить модулю о том, что у вас на форме есть такое поле, необходимо в options задать объект zip_field со следующими полями.
Для наглядности рассмотрим ещё несколько типовых примеров конфигурирования адресной формы с нашими дискретными подсказками.
В форме ниже полагается, что название города и населённого пункта будет вводиться отдельно от названия региона и района. Также здесь все числовые компоненты адреса (дом, корпус, строение и квартира) вводятся в одно общее поле.
<div> <input id="js-Field1" placeholder="Регион или район"/> <input id="js-Field2" placeholder="Город или нас. пункт"/> <input id="js-Field3" placeholder="Территория или улица"/> <input id="js-Field4" placeholder="Дом, корп, стр и квартира"/> </div>
Конфигурация для этой формы будет иметь следующий вид.
//настраиваем подсказки для ввода адреса в нескольких полях var options = { fields: [ { id: 'js-Field1', levels: ['Region','District'] }, { id: 'js-Field2', levels: ['City','Place'], suggest_on_empty : true }, { id: 'js-Field3', levels: ['Site','Street'] }, { id: 'js-Field4', levels: ['House','Building','Structure','Flat'] }, ], limit : 7, user : 'demotoken', on_fetch : function( Suggestion, Address ) { console.log( Suggestion, Address ); } }; //запускаем дискретные подсказки AhunterSuggest.Address.Discrete( options );
Здесь мы персонально для поля с названием города установили флаг suggest_on_empty = true, так что когда пользователь заполнит первое поле с регионом и переключится на второе поле, ему автоматически будут предложены наиболее популярные города в выбранном регионе.
Кроме этого для всех полей формы мы выставили лимит на число показываемых подсказок limit = 7, а также установили колбэк, который будет получать от нашего модуля выбранную пользователем подсказку и соответствующий ей стандартизованный адрес. Чтобы данный колбэк работал, мы явно указали API-токен demotoken нашей учётной записи на Ахантере.
Ниже показан пример того, как это будет работать.
Рассмотренный здесь пример демонстрирует, как будет выглядеть ваша форма, если каждый компонент адреса вводить в отдельное адресное поле. Такая форма будет иметь столько полей, сколько адресных компонентов поддерживает Ахантер.
Для полноты картины здесь также добавлено поле, в котором пользователь может указать почтовый индекс, чтобы сузить область адресов, по которым в остальных полях формы будут выдаваться подсказки.
Разметка такой формы будет иметь следующий вид.
<div> <input id="js-ZipField" placeholder="Почтовый индекс"/> <input id="js-Field1" placeholder="Регион"/> <input id="js-Field2" placeholder="Район"/> <input id="js-Field3" placeholder="Город"/> <input id="js-Field4" placeholder="Населённый пункт"/> <input id="js-Field5" placeholder="Территория"/> <input id="js-Field6" placeholder="Улица"/> <input id="js-Field7" placeholder="Дом"/> <input id="js-Field8" placeholder="Корпус"/> <input id="js-Field9" placeholder="Строение"/> <input id="js-Field10" placeholder="Квартира"/> </div>
Код для запуска дискретных подсказок на этой форме с учётом поля с почтовым индексом:
//настраиваем подсказки для ввода адреса в нескольких полях var options = { zip_field: { id: 'js-ZipField' }, fields: [ { id: 'js-Field1', levels: ['Region'] }, { id: 'js-Field2', levels: ['District'] }, { id: 'js-Field3', levels: ['City'] }, { id: 'js-Field4', levels: ['Place'] }, { id: 'js-Field5', levels: ['Site'] }, { id: 'js-Field6', levels: ['Street'] }, { id: 'js-Field7', levels: ['House'] }, { id: 'js-Field8', levels: ['Building'] }, { id: 'js-Field9', levels: ['Structure'] }, { id: 'js-Field10', levels: ['Flat'] } ], suggest_on_empty : true }; //запускаем дискретные подсказки AhunterSuggest.Address.Discrete( options );
Чтобы было проще заполнять такую большую форму, мы выставили флаг suggest_on_empty = true для всей формы сразу, поэтому после заполнения первого поля, последующие поля можно вручную не заполнять, а сразу же выбирать предлагаемые варианты подсказок.
Также для упрощения можно сразу начать заполнять эту форму не с первого поля, а, например, с поля города или населённого пункта. В этом случае, как только пользователь выберет подходящий город из подсказок, все поля, расположенные выше него, заполнятся автоматически.
Вживую это будет выглядеть так.
Использование REST API дискретных подсказок напрямую без модуля ahunter_suggest.js может потребоваться, если вы хотите использовать подсказки в вашем приложении, не поддерживающем JavaScript или jQuery. В этом случае, как и с обычными адресными подсказками, следует использовать ту же самую API команду suggest/address. Однако для работы в дискретном режиме понадобится передавать дополнительные параметры, а также немного иначе оформлять сам запрос.
Дискретный режим команды suggest/address подразумевает, что адрес вводится не в одно поле, а в нескольких полях. Ввод адреса происходит в режиме реального времени в каком-то одном из этих полей. Всякий раз, когда пользователь вводит очередной символ в текущее поле, увеличивается количество информации, на основе которой Ахантер может предложить подсказки для этого поля. При этом информация, уже введённая в других полях, тоже должна учитываться.
Поэтому при вводе пользователем каждого нового символа в текущем поле ваше приложение должно объединять всю информацию, введённую к настоящему моменту во всех полях формы, в единый запрос и отсылать его Ахантеру для получения новых подсказок.
Для организации такого взаимодействия ваше приложение должно отслеживать события, возникающие, когда происходят изменения в каком-либо поле вашей адресной формы. При возникновении такого события приложение должно отсылать текст, введенный к настоящему моменту во всех полях формы, в виде специально оформленного запроса сервису для получения подсказок для той части адреса, для которой предназначено текущее редактируемое поле формы.
Получив ответ от Ахантера, ваше приложение должно извлечь из него предложенные подсказки и показать их пользователю, предоставив тем самым возможность выбрать подходящий вариант для заполнения текущего поля.
После того, как пользователь выбрал подходящую подсказку, ваше приложение может запросить у Ахантера полную информацию о выбранном адресном объекте, например, его географические координаты или коды по справочникам ФИАС и КЛАДР. Для этого каждая подсказка снабжается уникальным идентификатором-сигнатурой. Когда пользователь выбирает подсказку, ваше приложение может брать соответствующую ей сигнатуру и отсылать её с помощью API команды fetch/address. В качестве ответа сервис вернёт структурированный адрес с полной информацией о нём.
Вся информация, которую пользователь ввёл в вашу форму, должна быть отправлена Ахантеру, чтобы он подобрал подходящие подсказки. При проектировании вашей адресной формы нужно решить, какие компоненты адреса, поддерживаемые Ахантером, будут вводиться в те или иные поля формы. Для этого нужно посмотреть нашу табличку с адресными компонентами, приведённую в начале данной статьи.
В этой таблице каждый компонент адреса имеет свой однобуквенный идентификатор (см. колонку ID в нашей таблице). Все идентификаторы адресных компонентов, соответствующие конкретному полю вашей формы, нужно объединить в единую строку. Например, если в первое поле вашей формы вы планируете вводить регион и административный район адреса, то, согласно нашей таблице, идентификаторы этих компонентов образуют строку – rd, потому что у региона в нашей таблице указан идентификатор r, а у района – идентификатор d. Для определённости далее такую строку будем называть адресным тэгом поля. Адресный тэг нужен просто, чтобы при отправке Ахантеру запроса сообщать, каким именно компонентам адреса соответствует информация, взятая с каждого поля вашей формы.
При формировании адресного тэга поля, нужно учитывать следующее правило. В строке адресного тэга должны быть перечислены только соседние по нашей таблице компоненты адреса. Например, нельзя поле формы привязать к регионам (r) и к городам (c), образуя тем самым тэг rc, минуя при этом компонент с районами (d). Это ограничение вытекает из специфики почтовой адресации – если мы пропустим и не будем указывать район, которому принадлежит город, то уникальность адресации города может быть нарушена, т.к. в двух разных районах могут присутствовать города с одинаковым названием.
Кроме этого правила, есть ещё одно очевидное ограничение - нельзя один и тот же компонент адреса привязывать сразу к нескольким разным полям вашей формы. Т.е. один и тот же идентификатор адресного компонента не должен встречаться в двух адресных тэгах двух разных полей вашей формы.
Теперь у нас есть вся информация, чтобы объединить её и отправить Ахантеру в качестве запроса. Для этого нужно взять текущее значение каждого поля вашей формы, заключить его в квадратные скобки и перед скобками поставить адресный тэг этого поля. Полученные таким образом строки нужно объединить в одну единую строку запроса. Ниже показана частично заполненная пользователем форма и соответствующие ей фрагменты запроса.
Здесь первое поле предназначено для ввода названия региона и района – адресный тэг rd. Во второе поле пользователь будет вводить имя города (c) и населённого пункта (p) – адресный тэг cp. Третье поле предназначено для территорий (t) и улиц (s) – адресный тэг ts. В последнее поле будут вводиться все числовые компоненты адреса (дом, корпус, строение и квартира), потому адресный тэг этого поля – hbuf.
Если объединить все фрагменты запроса этой формы в одну общую строку, то получим следующий запрос.
rd[обл Московская, р-н Раменский]cp[г Раменское]ts[ул Беговая]hbuf[д]
Именно в таком виде он и должен быть отправлен Ахантеру, чтобы получить подсказки для последнего поля формы. Поскольку это запрос дискретных подсказок, Ахантер будет формировать их только для последнего поля. В данном примере, подсказки будут предложены для номера дома, корпуса, строения и квартиры.
Если кроме адресных компонентов у вас на форме есть поле, куда пользователь может ввести почтовый индекс, чтобы сузить область поиска, то информацию из этого поля также нужно включить в запрос. Индекс нельзя объединять с остальными полями формы, поэтому для его передачи должен использовать отдельный адресный тэг – z.
Предположим, что адресная форма из рассмотренного примера имеет дополнительное поле для явного ввода почтового индекса. Пусть эта форма уже частично заполнена, как показано ниже.
Поскольку пользователь явно указал почтовый индекс, эта информация должна быть оформлена в виде фрагмента запроса z[140128]. Если при этом пользователь выбрал для заполнения поле с улицей, то итоговый запрос, который нужно отправить сервису, чтобы получить подсказки для улицы, будет выглядеть так.
z[140128]rd[обл Московская]ts[]
Есть ещё одно правило, которое следует учитывать при формировании таких запросов. Символы квадратных скобок являются служебными, поэтому если пользователь введёт их в само поле вашей формы то, перед формированием запроса их следует экранировать обратным слэшем. Аналогично следует поступать с символом самого обратного слэша, в случае, если пользователь ввёл его в каком-то поле вашей формы. Например, если в приведённой выше форме в последнем поле пользователь ввёл дом 1\2, соответствующий этому полю фрагмент запроса будет выглядеть так hbuf[дом 1\\2].
Приведенный ниже запрос отсылает сервису запрос дискретных подсказок rd[мос], введенный к настоящему моменту пользователем в поле, предназначенное для ввода региона и района. По этому запросу сервис должен сформировать подсказки с регионами и районами.
В данном запросе используются следующие параметры.
Рассмотрим более подробно все параметры, которые сервис может получать в рамках данной команды в режиме выдачи дискретных подсказок.
Обязательные параметры для выполнения запроса.
Опциональные параметры.
Приведенный ниже запрос отсылает сервису на обработку запрос дискретных подсказок rd[москва]ts[ул] с дополнительными параметрами.
В данном запросе используются следующие параметры.
Ответ Ахантера в формате JSON на запрос дискретных подсказок имеет точно такую же структуру и вид, как и ответ в формате JSON на запрос обычных адресных подсказок. Описание этого ответа можно посмотреть здесь.
Также как и с JSON-форматом, ответ Ахантера на запрос дискретных подсказок в формате XML аналогичен ответу, который сервис возвращает при запросе обычных адресных подсказок. Посмотреть описание этого ответа можно по следующей ссылке.