От автора: согласитесь, что регистрация на сайте – в данное время это довольно-таки обыденная и повсеместная вещь, а значит, разработчикам, конечно же, приходится формировать ее функционал, разрабатывая тот или иной проект.
Собственно, сам процесс регистрации – это довольно простая задача, которая заключается в простом сохранении данных, введенных в поля формы. Другое дело это визуальная составляющая и процесс валидации добавленной информации, так как зачастую пользователи вводят далеко не то, что мы ожидаем, а это может привести к ошибкам. И что бы избежать этого, довольно часто практикуют использование определенных наборов готовых вариантов, из которых посетитель выберет наиболее подходящий и таким самым не допустит ошибок в наборе.
Что делать, если необходимо предоставить возможность добавления адреса проживания пользователя, причем, включая как страну и город, так и возможно регион (при этом нет ограничения в месте проживания пользователя). В этом случае, предоставить готовый набор вариантов, достаточно проблематично, так как в масштабах всей нашей планеты, это просто огромное количество информации. Конечно, можно вывести на экран несколько текстовых полей, для последующего заполнения, но опять же не всегда этого удобно и хорошо.
Поэтому в данном уроке мы с Вами поговорим о том, как реализовать на сайте специальное поле, для ввода адреса проживания, с возможностью авто заполнения, что позволит предоставить пользователю выбор определенных вариантов, в зависимости от набираемой информации. И поможет нам в этом довольно интересный и функциональный сервис от Google, под названием Place Autocomplete.
Итак, задача данного урока – это получение от пользователя наиболее полной информации, о его месте проживания, а значит, как было сказано выше, простое текстовое поле для ввода информации, просто не подойдет. Поэтому мы реализуем интерактивный виджет, который будет предлагать пользователю выбрать один из сформированных вариантов мест, в зависимости, от набираемой информации в специальном текстовом поле.
Для данного урока я подготовил следующий тестовый сайт:
При этом, не обращайте внимание на огромное количество полей, они понадобятся далее для демонстрации работы скрипта и конечно же их заполнять не нужно и в идеале, они могут быть вообще скрытыми. За исключением первого поля, в которое пользователь будет вводить информацию о своем адресе. Карта, которая размещается слева, нужна для показа выбранного адреса на экране.
Как было сказано выше, виджет Autocomplete, мы реализуем, используя сервис Place, от Google Maps, а значит для начала, давайте подключим API указанного сервиса.
<script src="https://maps.googleapis.com/maps/api/js?key=api_key&libraries=places&callback=initMap"></script>
При этом не забывайте что для работы API, необходимо сгенерировать специальный token (ключ), который передается через GET параметры, при запросе библиотеки. В текущем уроке я не буду на этом останавливаться, так как на нашем сайте есть уроки по данной теме.
Обратите внимание что при запросе библиотеки, передается параметр callback=initMap, который указывает какая функция будет вызвана, после загрузке библиотеки. А значит, давайте ее опишем:
<script> var autocompletes, marker, infowindow, map; function initMap() { }
Конечно, код мы будем писать постепенно. На данном этапе мы объявили четыре глобальные переменные, которые будут хранить следующее:
autocompletes – объект виджета autocomplete;
marker – объект маркера, который будет отображаться в центре выбранного адреса;
Infowindow – объект всплывающей подсказки, которая будет отображать выбранный адрес;
map — объект карты Google maps.
Далее инициализируем карту и сохраняем объекты в выше указанные переменные:
map = new google.maps.Map(document.getElementById('map'), { center: {lat: -33.8688, lng: 151.2195}, zoom: 13 }); infowindow = new google.maps.InfoWindow(); marker = new google.maps.Marker({ map: map });
Для инициализации карты, необходимо создать объект Map() и при вызове конструктора передать в виде литерал-объекта, координаты центра карты. После этого можно создать объект отображаемого на экране маркера, функция конструктор которого принимает, как раз объект ранее созданной карты.
После сохранения кода и обновления информации в браузере, на экране мы увидим карту, центр которой соответствует переданным координатам при ее создании:
Далее инициализируем виджет Autocomplete:
var inputs = document.querySelector('#address'); autocompletes = new google.maps.places.Autocomplete(inputs);
Для этого создаем его объект, причем в функцию конструктор, обязательно необходимо передать поле формы, в которое пользователь будет вводить адрес.
Как обычно сохраняем изменения и переходим в браузер для просмотра результатов, при этом начнем вводить интересующий адрес в поле адреса.
Теперь, давайте опишем функцию обработчик события смены адреса пользователем, которое именуется как place_changed. Данная функция необходима для смены центра карты при выборе соответствующего адреса в виджете, а так же разбора его на отдельные составляющие.
Указанное событие будет срабатывать каждый раз, когда пользователь будет выбирать новый адрес в выпадающем списке. Для этого добавим следующие строки кода.
google.maps.event.addListener(autocompletes, 'place_changed', function () { marker.setVisible(false); infowindow.close(); var place = autocompletes.getPlace(); if (!place.geometry) { window.alert("Error"); return; } if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); } else { window.alert("Error"); } marker.setIcon(({ url: place.icon, scaledSize: new google.maps.Size(35, 35) })); marker.setPosition(place.geometry.location); marker.setVisible(true); var address = ''; if (place.address_components) { address = [ (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '') ].join(' '); } infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address); infowindow.open(map, marker); });
Метод addListener(), позволяет задать обработчик определенного события. При вызове указанного метода, первым аргументом передается элемент, в виде объекта, для которого регистрируется обработчик события, в нашем случае это autocompletes. Далее, вторым параметром передаем имя интересующего события и третьим параметром — описываем функцию, которая будет вызвана на исполнение.
В коде функции, первым делом скрывает все отображаемые элементы, в нашем случае это маркеры и всплывающие подсказки:
marker.setVisible(false); infowindow.close();
Для получения выбранного места, необходимо вызвать на исполнение метод getPlace() у объекта autocompletes. Причем, метод вернет довольно сложный объект, в котором хранится полная информация о выбранном адресе.
var place = autocompletes.getPlace();
Для смены центра карты используется метод map.fitBounds(place.geometry.viewport), который в качестве первого аргумента принимает объект с интересующими координатами, который располагается в свойстве place.geometry.viewport.
Теперь при сохранении информации мы увидим, что центр карты меняется при каждой смене адреса. Обратите внимание, что в объекте place, есть свойство address_components, в котором содержится полная информация о выбранном адресе:
Содержимое этого свойства используется для формирования всплывающей подсказки:
var address = ''; if (place.address_components) { address = [ (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '') ].join(' '); } infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address); infowindow.open(map, marker);
И записи отдельный составляющих выбранного адреса в поля формы:
document.getElementById('latitude').value = place.geometry.location.lat(); document.getElementById('longitude').value = place.geometry.location.lng(); var city = ''; var street = ''; var house = ''; var region = ''; var country = ''; var tmp = ''; console.log(place); place.address_components.forEach(function(item, i, arr) { tmp = item.long_name; if(item.types) { item.types.forEach(function(t) { switch (t) { case 'street_number' : house = tmp; break; case 'route' : street = tmp; break; case 'administrative_area_level_1' : case 'administrative_area_level_2' : region = tmp; break; case 'country' : country = tmp; break; case 'postal_town' : case 'locality' : city = tmp; break; } }); } }); document.getElementById('city').value = city; document.getElementById('street').value = street; document.getElementById('house').value = house; document.getElementById('region').value = region; document.getElementById('country').value = country;
Таким образом, при выборе адреса в виджете, на экране мы увидим следующий результат:
Согласитесь это очень удобно, так как пользователь выбирает интересующий для него адрес, а мы получаем полную информацию по нему, которую можно сохранить в базу данных. При этом замете, что карта – это необязательный атрибут и ее можно удалить, как и вспомогательные поля, таким образом, останется всего лишь одно поле для ввода адреса.
Полный код тестового сайта, будет прикреплен в исходниках к данному уроку, как и видео версия, в которой более подробно рассмотрена каждая строка кода. На этом урок завершен. Всего Вам доброго и удачного кодирования!