(function ($) { 'use strict'; var DEFAULT_CENTER = [35.6892, 51.3890]; var maps = {}; var markers = {}; function loadLeaflet(callback) { if (typeof L !== 'undefined') { callback(); return; } var attempts = 0; var check = setInterval(function () { attempts++; if (typeof L !== 'undefined') { clearInterval(check); callback(); } else if (attempts > 100) { clearInterval(check); } }, 50); } function parsePosition(val) { if (!val) { return null; } var parts = String(val).split(','); if (parts.length >= 2) { var lat = parseFloat(parts[0].trim()); var lng = parseFloat(parts[1].trim()); if (!isNaN(lat) && !isNaN(lng)) { return [lat, lng]; } } return null; } function reverseGeocode(lat, lng, addressSelector) { var $field = $(addressSelector); if (!$field.length) { return; } $.getJSON(base_path + '/reverse-geocode/' + lat + ',' + lng, function (data) { if (data && data.address) { $field.val(data.address).trigger('change'); } }); } function createMap(mapId, $wrapper, addressSelector, positionField, fillAddress) { var initial = null; if (positionField) { initial = parsePosition($(positionField).val()); } var center = initial || DEFAULT_CENTER; var zoom = initial ? 15 : 6; var map = L.map(mapId, { scrollWheelZoom: true }).setView(center, zoom); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }).addTo(map); markers[mapId] = null; if (initial) { markers[mapId] = L.marker(initial).addTo(map); } map.on('click', function (e) { var lat = e.latlng.lat; var lng = e.latlng.lng; if (markers[mapId]) { markers[mapId].setLatLng(e.latlng); } else { markers[mapId] = L.marker(e.latlng).addTo(map); } if (positionField) { $(positionField).val(lat + ',' + lng); } if (fillAddress && addressSelector) { reverseGeocode(lat, lng, addressSelector); } $wrapper.find('.osm-map-toggle').addClass('btn-info'); }); if (navigator.geolocation && !initial) { navigator.geolocation.getCurrentPosition(function (position) { map.setView([position.coords.latitude, position.coords.longitude], 12); }); } maps[mapId] = map; setTimeout(function () { map.invalidateSize(); }, 250); } function initWrapper($wrapper) { if ($wrapper.data('osm-initialized')) { return; } $wrapper.data('osm-initialized', true); var mapId = $wrapper.data('map-id'); var addressSelector = $wrapper.data('address-selector'); var positionField = $wrapper.data('position-field'); var fillAddress = $wrapper.data('fill-address') !== 0 && $wrapper.data('fill-address') !== '0'; var $container = $('#' + mapId); var $toggle = $wrapper.find('.osm-map-toggle'); if (positionField && $(positionField).val()) { $toggle.addClass('btn-info'); } $toggle.on('click', function () { if ($container.is(':visible')) { $container.slideUp(); return; } $container.slideDown(function () { loadLeaflet(function () { if (!maps[mapId]) { createMap(mapId, $wrapper, addressSelector, positionField, fillAddress); } else { maps[mapId].invalidateSize(); } }); }); }); } function scan(root) { $(root || document).find('.osm-address-map-wrapper').each(function () { initWrapper($(this)); }); } $(document).ready(function () { scan(); }); $(document).on('shown.bs.modal', function (e) { scan(e.target); }); window.OsmAddressMap = { scan: scan, invalidate: function (mapId) { if (maps[mapId]) { maps[mapId].invalidateSize(); } } }; })(jQuery);