1d70512abSGreg Roach<?php 2d70512abSGreg Roach 310e06497SGreg Roachdeclare(strict_types=1); 410e06497SGreg Roach 5d70512abSGreg Roachuse Fisharebest\Webtrees\I18N; 6d70512abSGreg Roach 77c2c99faSGreg Roach/** 87c2c99faSGreg Roach * @var array<mixed> $data 9c9c6f2ecSGreg Roach * @var object $leaflet_config 107c2c99faSGreg Roach */ 117c2c99faSGreg Roach 12d70512abSGreg Roach?> 13dd6b2bfcSGreg Roach 14*681f977fSGreg Roach<div class="row gx-1 wt-places-tab-wrapper wt-fullscreen-container"> 15*681f977fSGreg Roach <div class="col-sm-9"> 16*681f977fSGreg Roach <div id="wt-map" class="wt-ajax-load wt-map" dir="ltr"></div> 17*681f977fSGreg Roach </div> 18*681f977fSGreg Roach <div class="col-sm-3"> 19*681f977fSGreg Roach <ul class="wt-map-sidebar list-unstyled mb-0"></ul> 20*681f977fSGreg Roach </div> 21dd6b2bfcSGreg Roach</div> 22dd6b2bfcSGreg Roach 2374b9ba3fSGreg Roach<script> 24ffb44950SGreg Roach 'use strict'; 25dd6b2bfcSGreg Roach 2689b00848SDavid Drury (function () { 27728c8c27SGreg Roach const config = <?= json_encode($leaflet_config, JSON_THROW_ON_ERROR) ?>; 28dd6b2bfcSGreg Roach 29dd6b2bfcSGreg Roach let map = null; 3075f2a483SDavid Drury const sidebar = document.querySelector('.wt-map-sidebar'); 3189b00848SDavid Drury 3289b00848SDavid Drury const scrollOptions = { 3389b00848SDavid Drury behavior: "smooth", 34aeea31bdSGreg Roach block: "nearest", 3589b00848SDavid Drury inline: "start" 3689b00848SDavid Drury }; 37597fb44bSDavid Drury 38597fb44bSDavid Drury // Map components 39dd6b2bfcSGreg Roach let markers = L.markerClusterGroup({ 40dd6b2bfcSGreg Roach showCoverageOnHover: false, 41dd6b2bfcSGreg Roach }); 42dd6b2bfcSGreg Roach 43f352d954SDavid Drury /** 44f352d954SDavid Drury * Passed to resetControl to 45f352d954SDavid Drury * perform necessary reset actions on map 46b2e5f20eSGreg Roach * 47b2e5f20eSGreg Roach * @param {Event} event 48f352d954SDavid Drury */ 49b2e5f20eSGreg Roach let resetCallback = function (event) { 50b2e5f20eSGreg Roach event.preventDefault(); 5157ef7ac6Smiqrogroove map.flyToBounds(markers.getBounds(), {padding: [50, 30], maxZoom: 15 }); 52f352d954SDavid Drury } 53dd6b2bfcSGreg Roach 54dd6b2bfcSGreg Roach /** 55dd6b2bfcSGreg Roach * 56dd6b2bfcSGreg Roach * @private 57dd6b2bfcSGreg Roach */ 58dd6b2bfcSGreg Roach let _drawMap = function() { 59b7b71725SGreg Roach map = webtrees.buildLeafletJsMap('wt-map', config, resetCallback); 60dd6b2bfcSGreg Roach }; 61dd6b2bfcSGreg Roach 62597fb44bSDavid Drury /** 63597fb44bSDavid Drury * 64597fb44bSDavid Drury * @private 65597fb44bSDavid Drury */ 66597fb44bSDavid Drury let _buildMapData = function() { 67728c8c27SGreg Roach let data = <?= json_encode($data, JSON_THROW_ON_ERROR) ?>; 68dd6b2bfcSGreg Roach 69597fb44bSDavid Drury if (data.features.length === 0) { 70597fb44bSDavid Drury map.fitWorld(); 7189b00848SDavid Drury sidebar.innerHTML = '<div class="bg-info text-white text-center">' + <?= json_encode(I18N::translate('Nothing to show'), JSON_THROW_ON_ERROR) ?> + '</div>'; 72597fb44bSDavid Drury } else { 7389b00848SDavid Drury sidebar.innerHTML = ''; 74597fb44bSDavid Drury let geoJsonLayer = L.geoJson(data, { 75dd6b2bfcSGreg Roach pointToLayer: function(feature, latlng) { 76dd6b2bfcSGreg Roach return new L.Marker(latlng, { 77dd6b2bfcSGreg Roach icon: L.BeautifyIcon.icon({ 78dd6b2bfcSGreg Roach icon : feature.properties.icon["name"], 79dd6b2bfcSGreg Roach borderColor : "transparent", 8080993423SGreg Roach backgroundColor: feature.properties.icon["color"], 81dd6b2bfcSGreg Roach iconShape : "marker", 8280993423SGreg Roach textColor : "white", 83dd6b2bfcSGreg Roach }), 84dd6b2bfcSGreg Roach title: feature.properties.tooltip, 85dd6b2bfcSGreg Roach id : feature.id, 86dd6b2bfcSGreg Roach }) 87dd6b2bfcSGreg Roach .on("popupopen", function(e) { 88*681f977fSGreg Roach let item = document.querySelector('.wt-places-tab-wrapper [data-wt-feature-id="' + e.target.feature.id + '"]'); 8989b00848SDavid Drury item.classList.add('messagebox'); 9089b00848SDavid Drury item.scrollIntoView(scrollOptions); 91dd6b2bfcSGreg Roach }) 92dd6b2bfcSGreg Roach .on("popupclose", function() { 9389b00848SDavid Drury sidebar.childNodes.forEach(e => e.classList.remove('messagebox')); 94dd6b2bfcSGreg Roach }); 95dd6b2bfcSGreg Roach }, 96dd6b2bfcSGreg Roach onEachFeature: function(feature, layer) { 97dd6b2bfcSGreg Roach layer.bindPopup(feature.properties.summary); 98*681f977fSGreg Roach sidebar.innerHTML += `<li class="mb-1 wt-page-options-value" data-wt-feature-id=${feature.id}>${feature.properties.summary}</li>`; 99dd6b2bfcSGreg Roach }, 100dd6b2bfcSGreg Roach }); 101dd6b2bfcSGreg Roach markers.addLayer(geoJsonLayer); 102597fb44bSDavid Drury map.addLayer(markers); 10357ef7ac6Smiqrogroove map.fitBounds(markers.getBounds(), {padding: [50, 30], maxZoom: 15}); 104dd6b2bfcSGreg Roach } 105dd6b2bfcSGreg Roach }; 106dd6b2bfcSGreg Roach 10789b00848SDavid Drury // Can't use window.onload here. seems to be because of AJAX loading 10889b00848SDavid Drury const _loadListeners = function() { 109dd6b2bfcSGreg Roach // Activate marker popup when sidebar entry clicked 110*681f977fSGreg Roach sidebar.querySelectorAll('.wt-places-tab-wrapper [data-wt-feature-id]').forEach((element) => { 111815856a7SGreg Roach const eventId = parseInt(element.dataset.wtFeatureId); 11289b00848SDavid Drury 11389b00848SDavid Drury element.addEventListener('click', () => { 114dd6b2bfcSGreg Roach // first close any existing 115dd6b2bfcSGreg Roach map.closePopup(); 116dd6b2bfcSGreg Roach //find the marker corresponding to the clicked event 117815856a7SGreg Roach const mkrLayer = markers.getLayers().filter(function (v) { 11889b00848SDavid Drury return v.feature !== undefined && v.feature.id === eventId; 119dd6b2bfcSGreg Roach }); 12089b00848SDavid Drury 121dd6b2bfcSGreg Roach let mkr = mkrLayer.pop(); 12289b00848SDavid Drury 123dd6b2bfcSGreg Roach markers.zoomToShowLayer(mkr, function (e) { 124dd6b2bfcSGreg Roach mkr.openPopup(); 125dd6b2bfcSGreg Roach }); 12689b00848SDavid Drury }); 12789b00848SDavid Drury 12889b00848SDavid Drury // stop click on a person also opening the popup 12989b00848SDavid Drury element.querySelectorAll('a').forEach((el) => { 13089b00848SDavid Drury el.addEventListener('click', (e) => { 131dd6b2bfcSGreg Roach e.stopPropagation(); 132dd6b2bfcSGreg Roach }); 133597fb44bSDavid Drury }); 13489b00848SDavid Drury }); 135815856a7SGreg Roach }; 136dd6b2bfcSGreg Roach 137597fb44bSDavid Drury _drawMap(); 138597fb44bSDavid Drury _buildMapData(); 13989b00848SDavid Drury _loadListeners(); 140597fb44bSDavid Drury })(); 141dd6b2bfcSGreg Roach</script> 142