В RSForm есть поле типа "Карты Гугл", предусмотрен функционал геолокации. Суть его такова: на карте маркер, вы таскаете маркет по карте и в текстовом поле появляется адрес (или координаты) местоположения этого маркера. А что если мы хотим определить местоположение абонента автоматически, чтоб маркер сам туда перенесся? Вот решение этой задачи:
файл /administrator/components/com_rsform/helpers/fields/textbox.php
где-то внизу файла есть функция function generateMap(), обеспечивающая базовый функционал, и эту функцию мы скорректируем. Вот так она будет выглядеть:
public function generateMap() {
$id = $this->getProperty('componentId');
$zoom = (int) $this->getProperty('MAPZOOM', 2);
$center = $this->getProperty('MAPCENTER', '39.5500507,-105.7820674');
$geo = $this->getProperty('GEOLOCATION', 'NO');
$address = $this->getProperty('MAPRESULT', 'ADDRESS');
$name = $this->getProperty('NAME');
$mapType = $this->getProperty('MAPTYPE', 'ROADMAP');
$script = '
var rsformmap'.$id.';
var geocoder;
var rsformmarker'.$id.';
function rsfp_initialize_map'.$id.'() {
var message = document.getElementById("message");
geocoder = new Google.maps.Geocoder();
var rsformmapDiv'.$id.' = document.getElementById(\'rsform-map'.$id.'\');
rsformmap'.$id.' = new Google.maps.Map(rsformmapDiv'.$id.', {
center: new Google.maps.LatLng('.$center.'),
zoom: '.$zoom.',
mapTypeId: Google.maps.MapTypeId.'.$mapType.',
streetViewControl: false
});
rsformmarker'.$id.' = new Google.maps.Marker({
map: rsformmap'.$id.',
position: new Google.maps.LatLng('.$center.'),
draggable: true
});
document.getElementById("geoButton").addEventListener("click", function() { //включаем GPS /Wifi / мобильную геолокацию по клику на кнопку
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationFailure, {enableHighAccuracy: true, timeout: 10000, maximumAge: 60000});
}
else {
alert("Ваш браузер не поддерживает геолокацию");
}
});
function geolocationSuccess(position) {
//карта уже определена ранее, просто задаем новые корродинаты
var location = new Google.maps.LatLng(position.coords.latitude,position.coords.longitude);
rsformmap'.$id.'.setCenter(location); // центрируем карту по новым координатам
rsformmarker'.$id.'.setPosition (location); // и перемещаем сюда маркер
// Передаем полученный через GPS адрес в текстовое поле
var latlng = {lat: position.coords.latitude, lng: position.coords.longitude};
geocoder.geocode({"location": latlng}, function(results, status) {
if (status == Google.maps.GeocoderStatus.OK) {
if (results[0]) {';
if ($address == 'ADDRESS')
$script .= 'document.getElementById("'.$name.'").value = results[0].formatted_address;';
else
$script .= 'document.getElementById("'.$name.'").value = rsformmarker'.$id.'.getPosition().toUrlValue();';
$script .= '
}
}
});
message.innerHTML = "Местоположение определено";
}
function geolocationFailure(position) {
message.innerHTML = "Ошибка определения местоположения";
}
Google.maps.event.addListener(rsformmarker'.$id.', "drag", function() {
message.innerHTML = "";
geocoder.geocode({"latLng": rsformmarker'.$id.'.getPosition()}, function(results, status) {
if (status == Google.maps.GeocoderStatus.OK) {
if (results[0]) {';
if ($address == 'ADDRESS')
$script .= 'document.getElementById("'.$name.'").value = results[0].formatted_address;';
else
$script .= 'document.getElementById("'.$name.'").value = rsformmarker'.$id.'.getPosition().toUrlValue();';
$script .= '
}
}
});
});
';
$currentValue = $this->getValue();
if (!empty($currentValue)) {
if ($address == 'ADDRESS') {
$script .= '
geocoder.geocode({\'address\': document.getElementById(\''.$name.'\').value}, function(results, status) {
if (status == Google.maps.GeocoderStatus.OK) {
rsformmap'.$id.'.setCenter(results[0].geometry.location);
rsformmarker'.$id.'.setPosition(results[0].geometry.location);
}
});
';
}
else {
$script .= '
if (document.getElementById(\''.$name.'\') && document.getElementById(\''.$name.'\').value && document.getElementById(\''.$name.'\').value.length > 0 && document.getElementById(\''.$name.'\').value.indexOf(\',\') > -1) {
rsformCoordinates'.$id.' = document.getElementById(\''.$name.'\').value.split(\',\');
formPosition'.$id.' = new Google.maps.LatLng(parseFloat(rsformCoordinates'.$id.'[0]),parseFloat(rsformCoordinates'.$id.'[1]));
rsformmap'.$id.'.setCenter(formPosition'.$id.');
rsformmarker'.$id.'.setPosition(formPosition'.$id.');
}
';
}
}
$script .= '
}
Google.maps.event.addDomListener(window, \'load\', rsfp_initialize_map'.$id.');
';
if ($geo) {
$isAdress = $address == 'ADDRESS';
$script .= '
window.addEventListener("load", function(){
rsfp_addEvent(document.getElementById(\''.$name.'\'),\'keyup\', function() {
rsfp_geolocation(this.value,'.$id.',\''.$name.'\',rsformmap'.$id.',rsformmarker'.$id.',geocoder, '.(int) $isAdress.');
});
});
';
}
// Add the Google Maps API JS
if (!RSFormProFieldTextbox::$mapScript) {
$this->addCustomTag('<script src="https://maps.google.com/maps/api/js?key='.urlencode(RSFormProHelper::getConfig('google.api_key')).'" type="text/javascript"></script>');
// Do not load the script for every map field
RSFormProFieldTextbox::$mapScript = true;
}
// Add the custom script after the maps.js is loaded in the dom
$this->addCustomTag('<script type="text/javascript">'.$script.'</script>');
}
Местоположение определяется по клику на кнопке. В админке создаем кнопку (простую, не submit), даем ей имя geoButton. А также в любом месте нам нужен блочный HTML тэг (в смысле имеющий открывающий и закрывающий тэг <p></p> или <div></div> и т.д), которому приписываем id="message" – тут будут выводится служебные сообщения (местоположение определено, ошибка и т.д.).
Ну а работает это так: жмем на кнопку, если браузер поддерживает геолокацию (любой современный), пользователь разрешил браузеру определить местоположение (а на мобильнике к тому же разрешил геолокацию в системных настройках), то маркер перемещается в новую точку и карта центрируется по маркеру (если все прошло без ошибок), а в текстовом input появляется адрес маркера (или координаты - это настраивается в админке). Далее можно стандартно сместить маркер на карте поточнее. Проверено на стационарном компе (геолокация по IP) и на мобильнике (GPS + Wifi + локация по мобильным вышкам)