229 lines
9.7 KiB
JavaScript
229 lines
9.7 KiB
JavaScript
function geoloc_prefill(element_type, element_value, widget_name=null)
|
|
{
|
|
var selector = 'div[data-geolocation="' + element_type +'"]:first';
|
|
if (widget_name) {
|
|
selector = 'div[data-widget-name="' + widget_name + '"] ~ ' + selector;
|
|
}
|
|
$(selector).find('input').val(element_value).trigger('change');
|
|
$(selector).find('textarea').val(element_value).trigger('change');
|
|
$(selector).removeClass('widget-prefilled');
|
|
var $options = $(selector).find('option');
|
|
if ($options.length == 0) return;
|
|
|
|
var slugified_value = $.slugify(element_value);
|
|
var prefilled = false;
|
|
for (var i=0; i<$options.length; i++) {
|
|
var $option = $($options[i]);
|
|
if ($.slugify($option.val()) == slugified_value ||
|
|
$.slugify($option.text()) == slugified_value) {
|
|
$option.prop('selected', true);
|
|
$option.parent().trigger('change');
|
|
prefilled = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!prefilled) {
|
|
$($options[0]).prop('selected', true);
|
|
$($options[0]).parent().trigger('change');
|
|
}
|
|
}
|
|
|
|
function init_sync_from_template_address() {
|
|
// turn address-part-- class names into geolocation attributes, this allows
|
|
// address part elements to be both prefilled with some data and recognized
|
|
// as parts of the address block mechanism.
|
|
$('.address-part--number-and-street').attr('data-geolocation', 'number-and-street');
|
|
$('.address-part--house').attr('data-geolocation', 'house');
|
|
$('.address-part--road').attr('data-geolocation', 'road');
|
|
$('.address-part--city').attr('data-geolocation', 'city');
|
|
$('.address-part--postcode').attr('data-geolocation', 'postcode');
|
|
$('.address-part--country').attr('data-geolocation', 'country');
|
|
|
|
const widget_selector = '.JsonpSingleSelectWidget.template-address';
|
|
const hidden_parts_selector = '.hide-address-parts';
|
|
$(widget_selector + ' select').on('change', function() {
|
|
var data = $(this).select2('data');
|
|
var widget_name = $(this).parents('div.widget').data('widget-name');
|
|
if (data && data.length) {
|
|
var number_and_street = null;
|
|
var address = undefined;
|
|
if (typeof data[0].address == "object") {
|
|
address = data[0].address;
|
|
} else {
|
|
address = data[0];
|
|
}
|
|
var road = address.road || address.nom_rue;
|
|
var house_number = address.house_number || address.numero;
|
|
var city = address.city || address.nom_commune;
|
|
var postcode = address.postcode || address.code_postal;
|
|
if (house_number && road) {
|
|
number_and_street = house_number + ' ' + road;
|
|
} else {
|
|
number_and_street = road;
|
|
}
|
|
geoloc_prefill('number-and-street', number_and_street, widget_name);
|
|
geoloc_prefill('house', house_number, widget_name);
|
|
geoloc_prefill('road', road, widget_name);
|
|
geoloc_prefill('city', city, widget_name);
|
|
geoloc_prefill('postcode', postcode, widget_name);
|
|
geoloc_prefill('country', address.country, widget_name);
|
|
}
|
|
});
|
|
|
|
$('input.wcs-manual-address').on('change', function() {
|
|
var widget = $(this).parents('div.widget');
|
|
widget.nextUntil(widget_selector, 'div[data-geolocation]').find('input').attr('readonly', this.checked ? null : 'readonly');
|
|
widget.nextUntil(widget_selector, 'div[data-geolocation]').find('textarea').attr('readonly', this.checked ? null : 'readonly');
|
|
if (this.checked) {
|
|
widget.nextUntil(widget_selector, 'div[data-geolocation]:not(.template-address):not(.MapWidget)').attr('hidden', null)
|
|
} else if (widget.is(hidden_parts_selector)) {
|
|
widget.nextUntil(widget_selector, 'div[data-geolocation]:not(.template-address):not(.MapWidget)').attr('hidden', 'hidden')
|
|
}
|
|
});
|
|
|
|
if ($(widget_selector).length) {
|
|
$('div[data-geolocation] input, div[data-geolocation] textarea').attr('readonly', 'readonly')
|
|
if ($(widget_selector + hidden_parts_selector).length) {
|
|
$(widget_selector + hidden_parts_selector).nextUntil(widget_selector, 'div[data-geolocation]:not(.template-address):not(.MapWidget)').attr('hidden', 'hidden');
|
|
}
|
|
}
|
|
$(widget_selector).each(function(idx, elem) {
|
|
// enable manual address mode if there is an error in one of the manual address fields.
|
|
if ($(elem).nextUntil('.template-address', '[data-geolocation].widget-with-error').length) {
|
|
$(elem).find('input.wcs-manual-address').prop('checked', true).trigger('change');
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
$(function() {
|
|
init_sync_from_template_address();
|
|
$('form').on('wcs:block-row-added', function() {
|
|
init_sync_from_template_address();
|
|
});
|
|
$(document).on('set-geolocation', function(event, coords, options) {
|
|
var widget_name = $(event.target).parents('div.widget').data('widget-name');
|
|
$.getJSON(WCS_ROOT_URL + '/api/reverse-geocoding?lat=' + coords.lat + '&lon=' + coords.lng, function(data) {
|
|
unset_sync_callback()
|
|
if (data.err) return;
|
|
|
|
var $prefilled_by_id = $('div[data-geolocation="address-id"]');
|
|
if ($prefilled_by_id.length) {
|
|
// prefill by id first as the .change() event will empty the other
|
|
// address fields.
|
|
var option = $('<option></option>', {value: data.id, text: data.display_name});
|
|
option.appendTo($prefilled_by_id.find('select'));
|
|
$prefilled_by_id.find('select').val(data.id).change();
|
|
}
|
|
|
|
if (typeof(options) == 'undefined' || !options.force_house_number === false || data.address.house_number) {
|
|
geoloc_prefill('house', data.address.house_number, widget_name);
|
|
}
|
|
var number_and_street = null;
|
|
var street = data.address.road;
|
|
if (!street && data.address.pedestrian) {
|
|
street = data.address.pedestrian;
|
|
} else if (!street && data.address.footway) {
|
|
street = data.address.footway;
|
|
} else if (!street && data.address.path) {
|
|
street = data.address.path;
|
|
} else if (!street && data.address.cycleway) {
|
|
street = data.address.cycleway;
|
|
} else if (!street && data.address.park) {
|
|
street = data.address.park;
|
|
}
|
|
geoloc_prefill('road', street, widget_name);
|
|
if (street && data.address.house_number) {
|
|
number_and_street = data.address.house_number + ' ' + street;
|
|
} else {
|
|
number_and_street = street;
|
|
}
|
|
geoloc_prefill('number-and-street', number_and_street, widget_name);
|
|
geoloc_prefill('postcode', data.address.postcode, widget_name);
|
|
geoloc_prefill('city', data.address.village || data.address.town || data.address.city || data.address.locality || data.address.municipality || data.address.county, widget_name);
|
|
geoloc_prefill('country', data.address.country, widget_name);
|
|
$(document).trigger('wcs:set-last-auto-save');
|
|
set_sync_callback()
|
|
});
|
|
});
|
|
|
|
if ($('.qommon-map').length == 0 && $('.JsonpSingleSelectWidget.template-address').length == 0) {
|
|
/* if there's no map on the page, we do the geolocation without leaflet. */
|
|
if (navigator.geolocation) {
|
|
$('div[data-geolocation] label').addClass('activity');
|
|
navigator.geolocation.getCurrentPosition(
|
|
function (position) {
|
|
$('div[data-geolocation] label').removeClass('activity');
|
|
var coords = {lat: position.coords.latitude, lng: position.coords.longitude};
|
|
$(document).trigger('set-geolocation', coords);
|
|
},
|
|
function (error_msg) {
|
|
$('div[data-geolocation] label').removeClass('activity');
|
|
$($('div[data-geolocation] label')[0]).after(
|
|
'<span class="geoloc-error">' + error_msg.message + '</span>');
|
|
},
|
|
{timeout: 10000, maximumAge: 300000, enableHighAccuracy: false}
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
function set_sync_callback() {
|
|
var $map = $('.qommon-map');
|
|
if ($map.length == 0) return;
|
|
var $form = $map.parents('form');
|
|
if ($form.length == 0) return; // probably a geolocation map in sidebar
|
|
$form[0].wait_for_changes = false;
|
|
if (! $map.data('address-sync')) return;
|
|
$('div[data-geolocation]').on('change', 'input[type=text], textarea, select', function(event) {
|
|
if ($('.wcs-manual-address:checked').length && $(this).parents('.template-address').length == 0) {
|
|
// do not sync address and map is the address is being entered manually
|
|
// as it probably means the address isn't known and reverse/geocoding
|
|
// won't be correct.
|
|
return;
|
|
}
|
|
$form[0].wait_for_changes = true;
|
|
var address = '';
|
|
var found_city = false;
|
|
var found_country = false;
|
|
$(['number-and-street', 'house', 'road', 'postcode', 'city', 'country']).each(function(idx, elem) {
|
|
var part = $('div[data-geolocation="' + elem + '"]').find('input, textarea, select').val();
|
|
if (part) {
|
|
address += part + ' ';
|
|
if (elem == 'number-and-street' || elem == 'road' || elem == 'city') {
|
|
address += ', ';
|
|
}
|
|
if (elem == 'postcode' || elem == 'city') {
|
|
found_city = true;
|
|
}
|
|
if (elem == 'country') {
|
|
found_country = true;
|
|
}
|
|
}
|
|
});
|
|
if (found_city) {
|
|
if (!found_country && typeof(WCS_DEFAULT_GEOCODING_COUNTRY) !== 'undefined') {
|
|
address += WCS_DEFAULT_GEOCODING_COUNTRY;
|
|
}
|
|
$.getJSON(WCS_ROOT_URL + '/api/geocoding?q=' + address, function(data) {
|
|
if (data && $(data).length > 0) {
|
|
var coords = {lat: data[0].lat, lng: data[0].lon};
|
|
var map = $map[0].leaflet_map;
|
|
map.flyTo(coords);
|
|
if (map.marker === null) {
|
|
map.marker = L.marker([0, 0]);
|
|
map.marker.addTo(map);
|
|
}
|
|
$map.trigger('set-geolocation', [coords, {'trigger': false, 'force_house_number': false}]);
|
|
$form[0].wait_for_changes = false;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
function unset_sync_callback() {
|
|
$('div[data-geolocation]').off('change', 'input[type=text], textarea, select');
|
|
}
|
|
set_sync_callback();
|
|
});
|