Делаем адресные формы более привлекательными

ecc1f3d0a438cc09fd253a386a361019

Одно из основных направлений работы нашей компании — очистка и стандартизация клиентских данных. Наш софт может привести в порядок любую базу данных с информацией о клиентах: исправить ошибки и опечатки, восполнить недостающую информацию, обогатить данные дополнительными сведениями, устранить дубликаты.

К сожалению, однократной очистки часто бывает недостаточно: нужно не допустить попадания плохих и неполных данных в базу в будущем. Именно для решения этой задачи был разработан сервис подсказок, о котором мыписали ранее. Изначально подсказки предназначались для операторов, которым приходится вводить большое количество адресов, и были призваны ускорить их работу и сократить количество ошибок.

Однако, позже мы поняли, что сервис может быть полезен всем, кто так или иначе работает с клиентскими данными. Ниже я постараюсь показать, что могут подсказки, и как с их помощью сделать ввод адресов на вашем сайте удобным и очень простым процессом.

Все знают, что такое форма заполнения адреса: множество полей и потраченное время на их заполнение. Но настоящие проблемы начинаются, когда веб-мастер добавлет к форме валидацию. Один из популярных вариантов — список на 100500+ элементов и жёсткая проверка на соответствие данных справочнику.

Например, на прошлой неделе, когда мы хотели заказать пиццу на одном известном сайте, процесс ввода адреса неожиданно превратился в удивительный квест. Сначала мы увидели поле для ввода улицы, указали «Турчанинов переулок» и, не ожидая подвоха, нажали «Продолжить»:

37f1cefbfd626531ab62361d9aee796c

Тщетные попытки ввести «Турчанинов», «Турчанинов пер», «пер Турчанинов», «ТУРЧАНИНОВ» также не увенчались успехом. Если честно, хотелось уже заказать в другом месте. Но интерес закончить начатое перевесил негодование, и, в результате, мы ввели название крупной улицы неподалеку от офиса и нажали «ОК».

8c45a6896c6f6f2291d71bf4466a4f17

Да, это модальное окно с названием улицы. Нажимаем «Продолжить» и можем ввести дом.

d906eb25023648ce92e23ddcb04a8967

Других домов на этой улице не существует, конечно. Выбрали ближайший к нам, в комментарии к заказу указали правильный адрес и отправились праздновать, потратив 5 минут на ввод адреса.

Отличный пример как делать не надо.

А как сделать форму, которая будет удобна? Возьмём, для примера, страницу обращения в интернет-приёмную правительства Москвы:

688a4ccae544530d3c53124285eca45f

В принципе, неплохая для заполнения форма (при наличии свободного времени): много разных полей, не путаешься, что куда вводить, и нет назойливой валидации. Правда, на планшете и телефоне не очень удобно прыгать по полям. И немного отпугивает.

Можно разбить форму на несколько страниц: так она станет менее загруженной. Но это не уменьшит общего времени заполнения, поэтому мы пойдём по другому пути.

Перенесём страницу в прототип, чтобы проще было проектировать:

5cd0821916efb752f47031e529a14257

Сразу же возникает вопрос: можно ужать адресную информацию в одно поле? Или требуется разбиение на несколько элементов?

Скорее всего, за разные адреса отвечают разные инстанции, плюс для последующей аналитики было бы неплохо сохранить разбивку адреса по компонентам. Однако, никто не запрещает нам вводить информацию в одно поле, после чего распределять её на составляющие. Добавим основное поле ввода адреса и подключим к немуподсказки:

2a45a979638601a8e665c19f782f3e0c

Пример кода: подключаем подсказки по адресу к текстовому полю

<div class="form-group">
    <label for="address">Адрес</label><span class="required"> </span>
    <input type="text" class="form-control" id="address" placeholder="Введите адрес в свободной форме (до дома)">
</div>
$("#address").suggestions({
    serviceUrl: DADATA_API_URL + "/suggest/address",
    token: TOKEN,
    selectOnSpace: true
});

Теперь уберем лишнюю информацию, а нужную разобъем на две строки — регион с городом и улица с домом. Заодно подсветим введённые пользователем символы, чтобы упростить восприятие списка:

5ee04f33d9f2447067844b931fd6cd09

Пример кода: нестандартное форматирование списка подсказок

/* Подсветка совпадения в результатах поиска */
.autocomplete-suggestions strong {
    color: #3399FF;
    font-weight: normal;
}
$("#address").suggestions({
    serviceUrl: DADATA_API_URL + "/suggest/address",
    token: TOKEN,
    selectOnSpace: true,
    formatResult: self.formatResult
});

/**
 * Форматирование элемента списка подсказок в две строки.
 * При отрисовке списка подсказок вызывается для каждого элемента списка.
 * @param suggestion   Подсказка
 * @param currentValue Введенный пользователем текст
 * @returns {string} HTML для элемента списка подсказок
 */
formatResult: function (suggestion, currentValue) {
    var address = suggestion.data;
    // первая строка - регион, район, город
    var part1 = join([
        address.region,
        join([address.area_type, address.area], " "),
        join([address.city_type, address.city], " ")
    ]);
    // вторая строка - населенный пункт, улица и дом
    var part2 = join([
        join([address.settlement_type, address.settlement], " "),
        join([address.street_type, address.street], " "),
        join([address.house_type, address.house], " ")
    ]);
    // подсветка введенного пользователем текста
    var pattern = '(^|\\s+)(' + $.Suggestions.utils.escapeRegExChars(currentValue) + ')';
    part2 = part2.replace(new RegExp(pattern, 'gi'), '$1<strong>$2<\/strong>')
    var suggestedValue = part2 ?
        "<span class=\"autocomplete-suggestion-region\">" + part1 + "</span>" + "<br>  " + part2
        : part1;
    return suggestedValue;
}

В первую очередь подсказки возвращают информацию по городам и областям, затем по улицам, затем по домам. Москва и Санкт-Петербург в приоритете. Мы делаем форму для правительства Москвы, поэтому ограничим поиск одной Москвой:

a1f7f1fe5504fac761d0a632d042ba27

Пример кода: ограничиваем поиск конкретным регионом России

$("#address").suggestions({
    serviceUrl: DADATA_API_URL + "/suggest/address",
    token: TOKEN,
    selectOnSpace: true,
    onSearchStart: self.forceMoscow,
    formatResult: self.formatResult
});

/**
 * Ограничивает поиск Москвой
 * @param params Параметры ajax-запроса
 */
forceMoscow: function (params) {
    var query = params["query"];
    var pattern = /Москва/i;
    if (!pattern.test(query)) {
        query = "Москва " + query;
    }
    params["query"] = query;
}

Чтобы не появлялся скролл, будем показывать первые 7 из 10 подсказок (отсортированы они по релевантности, поэтому качество поиска не пострадает):

cc68be01f76d0e43b915a7a308b4acb9

Пример кода: фильтруем список подсказок

$("#address").suggestions({
    serviceUrl: DADATA_API_URL + "/suggest/address",
    token: TOKEN,
    selectOnSpace: true,
    maxHeight: 310,
    onSearchStart: self.forceMoscow,
    onSearchComplete: self.trimResults,
    formatResult: self.formatResult
});

/**
 * Фильтрует список подсказок
 * @param query       Введенный пользователем текст
 * @param suggestions Массив подсказок для введенного текста
 */
trimResults: function (query, suggestions) {
    suggestions.splice(7,3);
    suggestions.forEach(function(suggestion) {
        suggestion.value = suggestion.value.replace("Россия, ", "");
    })
}

Когда пользователь выбирает конкретный вариант из списка, в «Адрес» помещаем выбранное значение, а в остальные поля формы подставляем гранулярные поля адреса:

cee8f660c6d322d4cc564755f8e0b8a8

Пример кода: автоматически заполняем адрес из выбранной подсказки

$("#address").suggestions({
    serviceUrl: DADATA_API_URL + "/suggest/address",
    token: TOKEN,
    selectOnSpace: true,
    maxHeight: 310,
    onSearchStart: self.forceMoscow,
    onSearchComplete: self.trimResults,
    formatResult: self.formatResult,
    onSelect: function(suggestion) {
        if (suggestion.data) {
            this.value = self.formatSelected(suggestion);
            self.showSelected(suggestion);
        }
    }
});

/**
 * Заполняет поля формы гранулярными полями адреса из выбранной подсказки
 * @param suggestion Выбранная подсказка
 */
showSelected: function (suggestion) {
    var address = suggestion.data;
    $("#address-postal_code").val(address.postal_code);
    $("#address-region").val(
        join([address.region_type, address.region], " ")
    );
    $("#address-city").val(join([
        join([address.area_type, address.area], " "),
        join([address.city_type, address.city], " "),
        join([address.settlement_type, address.settlement], " ")
    ]));
    $("#address-street").val(
        join([address.street_type, address.street], " ")
    );
    $("#address-house").val(
        join([address.house_type, address.house], " ")
    );
}  // любите работать с кодом? 
   // У нас есть отличные вакансии http://hh.ru/employer/15589

Раз все поля теперь заполняются автоматически, мы можем сделать адресную часть формы более лаконичной:

dfd6d4c5e4720c6ee500717224ba6bbd

По аналогии делаем ФИО и получаем такую форму обратной связи:

55f3394df376d13ac9b663c4346e3587

Вживую можно посмотреть на демо-странице (+ исходники на гитхабе).

Получившаяся форма требует минимум затрат от веб-мастера, удобна для пользователя, подходит к вводу как на компьютере, так и на планшете или телефоне.

Представляете, если бы на каждом сайте: при покупке билета, оформлении заказа в интернет магазине или при заполнении формы регистрации — была такая простая процедура ввода данных? Если бы заполнение формы с любого устройства было максимально удобно и на это требовалось всего 5-10 секунд?

Предлагаем начать делать мир лучше уже сейчас! Подключайтесь к сервису и пробуйте, смотрите за реакцией пользователей, проводите a/b тестирование. И удачи вам с вашими клиентами!