From bf6365d63c8237c6eabb8dce3385f4f4b3e93571 Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:45:19 +0200 Subject: [PATCH 01/11] preserve filterVisible during pan and zoom --- croutonjs/meetingMap/js/gmapsDelegate.js | 46 +++++++++++++----------- croutonjs/meetingMap/js/meeting_map.js | 28 +++++++++++---- croutonjs/meetingMap/js/osmDelegate.js | 16 +++++++-- 3 files changed, 62 insertions(+), 28 deletions(-) diff --git a/croutonjs/meetingMap/js/gmapsDelegate.js b/croutonjs/meetingMap/js/gmapsDelegate.js index 1be89883..33d0a51e 100644 --- a/croutonjs/meetingMap/js/gmapsDelegate.js +++ b/croutonjs/meetingMap/js/gmapsDelegate.js @@ -15,15 +15,15 @@ function MapDelegate(in_config) { function isApiLoaded() { return gIsLoaded; } - function loadApi(f, args) { - var tag = document.createElement('script'); + async function loadApi(f, args) { + (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({ + key: config['api_key'], + v: "weekly", + }); + const { Map } = await google.maps.importLibrary("maps"); + const { AdvancedMarkerElement } = await google.maps.importLibrary("marker"); gIsLoaded = true; - if (typeof config['api_key'] === 'undefined') config['api_key'] = ""; - tag.src = "https://maps.googleapis.com/maps/api/js?key=" + config['api_key'] + "&callback=croutonMap.apiLoadedCallback"; - tag.defer = true; - tag.async = true; - var firstScriptTag = document.getElementsByTagName('script')[0]; - firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); + croutonMap.apiLoadedCallback(); }; function createMap(inDiv, inCenter) { g_icon_image_single = new google.maps.MarkerImage ( config.BMLTPlugin_images+"/NAMarker.png", new google.maps.Size(23, 32), new google.maps.Point(0,0), new google.maps.Point(12, 32) ); @@ -43,6 +43,7 @@ function MapDelegate(in_config) { 'draggableCursor': "pointer", 'scaleControl' : true, 'fullscreenControl': config.map_search ? true : false, + 'mapId': "DEMO_MAP_ID", }; if (inCenter) { myOptions = Object.assign(myOptions, { @@ -52,16 +53,16 @@ function MapDelegate(in_config) { } var pixel_width = inDiv.offsetWidth; var pixel_height = inDiv.offsetHeight; - + if ( (pixel_width < 640) || (pixel_height < 640) ) { - myOptions.scrollwheel = true; + myOptions.scrollwheel = true; myOptions.zoomControlOptions = { 'style': google.maps.ZoomControlStyle.SMALL }; } else { myOptions.zoomControlOptions = { 'style': google.maps.ZoomControlStyle.LARGE }; }; gInfoWindow = new google.maps.InfoWindow(); gMainMap = new google.maps.Map ( inDiv, myOptions ); - + return gMainMap; } function addListener(ev,f,once) { @@ -74,11 +75,14 @@ function MapDelegate(in_config) { ; } if (once) { - google.maps.event.addListenerOnce( gMainMap, e, f); + return google.maps.event.addListenerOnce( gMainMap, e, f); } else { - google.maps.event.addListener( gMainMap, e, f); + return google.maps.event.addListener( gMainMap, e, f); } } + function removeListener(f) { + f.remove(); + } function fitBounds(locations) { google.maps.event.addListenerOnce(gMainMap, "bounds_changed", function () { gMainMap.setZoom(parseInt(Math.min(gMainMap.getZoom(), config.maxZoom))); @@ -141,11 +145,11 @@ function MapDelegate(in_config) { if (knt == 0) { ret -= 1; } - } + } return ret; } function setZoom(filterMeetings, force=0) { - (force > 0) ? gMainMap.setZoom(force) : + (force > 0) ? gMainMap.setZoom(force) : gMainMap.setZoom(getZoomAdjust(false,filterMeetings)); } function getZoom() { @@ -214,7 +218,7 @@ function MapDelegate(in_config) { } }); }); - + // This is necessary to make the Spiderfy work gOms.addListener('click', function (marker) { marker.zIndex = 999; @@ -222,11 +226,11 @@ function MapDelegate(in_config) { gInfoWindow.open(gMainMap, marker); }); markers.forEach((marker)=>gOms.addMarker(marker)); - + } else markers.forEach((m)=>m.setMap(gMainMap)); } function createMarker ( inCoords, ///< The long/lat for the marker. - multi, + multi, inHtml, ///< The info window HTML inTitle, ///< The tooltip inIds @@ -237,7 +241,7 @@ function createMarker ( inCoords, ///< The long/lat for the marker. var is_clickable = (inHtml ? true : false); - var marker = new google.maps.Marker ( + var marker = new google.maps.Marker ( { 'position': new google.maps.LatLng(...inCoords), 'shadow': g_icon_shadow, 'icon': in_main_icon, @@ -349,7 +353,7 @@ function geoCallback( in_geocode_response ) { && config.bounds.south && config.bounds.south.trim()!== '' && config.bounds.west && config.bounds.west.trim()!== '') { geoCodeParams.bounds = new google.maps.LatLngBounds( - new google.maps.LatLng(config.bounds.south, config.bounds.west), + new google.maps.LatLng(config.bounds.south, config.bounds.west), new google.maps.LatLng(config.bounds.north, config.bounds.east)); } if (filterMeetings) @@ -405,9 +409,11 @@ function geoCallback( in_geocode_response ) { this.getGeocodeCenter = getGeocodeCenter; this.modalOn = modalOn; this.modalOff = modalOff; + this.removeListener = removeListener; } MapDelegate.prototype.createMap = null; MapDelegate.prototype.addListener = null; +MapDelegate.prototype.removeListener = null; MapDelegate.prototype.addControl = null; MapDelegate.prototype.setViewToPosition = null; MapDelegate.prototype.clearAllMarkers = null; diff --git a/croutonjs/meetingMap/js/meeting_map.js b/croutonjs/meetingMap/js/meeting_map.js index 24cb9e05..bcddf084 100644 --- a/croutonjs/meetingMap/js/meeting_map.js +++ b/croutonjs/meetingMap/js/meeting_map.js @@ -69,7 +69,11 @@ function MeetingMap(inConfig) { if (gDelegate.createMap(inDiv, loc)) { gDelegate.addListener('zoomend', function (ev) { if (shouldRedrawMarkers() && gAllMeetings) { - searchResponseCallback(); + if (listOnlyVisible) { + const oldValue = filterVisible(false); + searchResponseCallback(); + filterVisible(oldValue); + } else searchResponseCallback(); } }, false); if (config.map_search) { @@ -152,8 +156,9 @@ function MeetingMap(inConfig) { controlDiv.innerHTML = template(menuContext); controlDiv.querySelector("#nearbyMeetings").addEventListener('click', function (e) { retrieveGeolocation().then(position => { - filterVisible(false); + const oldValue = filterVisible(false); gDelegate.setViewToPosition(position, filterMeetingsAndBounds); + filterVisible(oldValue); }).catch(error => { console.error(error.message); $('.geo').removeClass("hide").addClass("show").html(`
${error.message}
`); @@ -173,7 +178,6 @@ function MeetingMap(inConfig) { let dropdownContent = document.getElementById("map-menu-dropdown"); if (dropdownContent.style.display == "inline-block") { dropdownContent.style.display = "none"; - filterVisible(false); } else dropdownContent.style.display = "inline-block"; }); @@ -406,8 +410,10 @@ function MeetingMap(inConfig) { jQuery("#bmlt-map").css("display", "block"); } function resetVisibleThenFilterMeetingsAndBounds(bounds) { - filterVisible(false); - filterMeetingsAndBounds(bounds); + const oldValue = filterVisible(false); + const ret = filterMeetingsAndBounds(bounds); + filterVisible(oldValue); + return ret; } function lookupLocation(fullscreen) { if (document.getElementById('goto-text').value != '') { @@ -582,8 +588,12 @@ function MeetingMap(inConfig) { function filterBounds(bounds) { return gAllMeetings.filter((meeting) => gDelegate.contains(bounds, meeting.latitude, meeting.longitude)); } + function showAllMeetings() { + filterVisible(false); + gDelegate.addListener('dragend', filterVisible, true); + } function filterVisible(on=true) { - if (on===listOnlyVisible) return; + if (on===listOnlyVisible) return on; let mtgs = on ? filterBounds(gDelegate.getBounds()) : gAllMeetings; let visible = mtgs.map((m)=>m.id_bigint); jQuery(".bmlt-data-row").each(function(index,row) { @@ -596,6 +606,12 @@ function MeetingMap(inConfig) { fitDuringFilter = true; jQuery("#filteringByVisibility").html(on?'✔':''); listOnlyVisible = on; + if (on) listener = gDelegate.addListener('dragstart', showAllMeetings, true); + else if (listener) { + gDelegate.removeListener(listener); + listener = null; + } + return !on; } function toggleVisible() { filterVisible(!listOnlyVisible); diff --git a/croutonjs/meetingMap/js/osmDelegate.js b/croutonjs/meetingMap/js/osmDelegate.js index 4cea2a20..0cf68205 100644 --- a/croutonjs/meetingMap/js/osmDelegate.js +++ b/croutonjs/meetingMap/js/osmDelegate.js @@ -65,12 +65,22 @@ function MapDelegate(config) { if (ev=='idle') { ev = 'moveend'; } + if (ev=='dragstart') { + ev = 'movestart'; + } + if (ev=='dragend') { + ev = 'moveend'; + } if (once) { gMainMap.once(ev, f); } else { gMainMap.on(ev, f); } + return {'event': ev, 'f': f}; } + function removeListener(o) { + gMainMap.off(o.event, o.f); + } function setViewToPosition(position, filterMeetings, extra=null) { var latlng = L.latLng(position.latitude, position.longitude); gMainMap.flyTo(latlng); @@ -80,7 +90,7 @@ function MapDelegate(config) { if (gMainMap.getZoom() != newZoom) { gMainMap.setZoom(newZoom); gMainMap.on('zoomend',function() { - gMainMap.off('zoomend'); + gMainMap.off('zoomend'); gMainMap.invalidateSize(); if (extra) { gMainMap.on('load moveend', extra); @@ -137,7 +147,7 @@ function MapDelegate(config) { if (knt == 0) { ret -= 1; } - } + } return ret; } function setZoom(filterMeetings, force=0) { @@ -380,6 +390,7 @@ function addControl(div,pos,cb) { function returnTrue() {return true;} this.createMap = createMap; this.addListener = addListener; + this.removeListener = removeListener; this.addControl = addControl; this.setViewToPosition = setViewToPosition; this.clearAllMarkers = clearAllMarkers; @@ -405,6 +416,7 @@ function addControl(div,pos,cb) { } MapDelegate.prototype.createMap = null; MapDelegate.prototype.addListener = null; +MapDelegate.prototype.removeListener = null; MapDelegate.prototype.addControl = null; MapDelegate.prototype.setViewToPosition = null; MapDelegate.prototype.clearAllMarkers = null; From 28076948acd7d8831bba050f1672600092bb3e80 Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:23:09 +0200 Subject: [PATCH 02/11] Add configuration parameter "filter_visible" --- crouton.php | 2 ++ croutonjs/meetingMap/js/gmapsDelegate.js | 25 +++++++++++++++--------- croutonjs/meetingMap/js/meeting_map.js | 1 + croutonjs/meetingMap/js/osmDelegate.js | 11 ++++++++--- croutonjs/meetingMap/meeting_map.php | 9 +++++---- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/crouton.php b/crouton.php index a62c4790..56b7f5da 100644 --- a/crouton.php +++ b/crouton.php @@ -73,6 +73,7 @@ class Crouton "has_languages" => '0', "has_common_needs" => '0', "has_venues" => '1', + "filter_visible" => '0', "include_city_button" => '1', "include_weekday_button" => '1', "include_unpublished" => '0', @@ -126,6 +127,7 @@ class Crouton "has_languages", "has_zip_codes", "has_venues", + "filter_visible", "has_common_needs" ]; private $waitMsg = ''; diff --git a/croutonjs/meetingMap/js/gmapsDelegate.js b/croutonjs/meetingMap/js/gmapsDelegate.js index 33d0a51e..1b1be154 100644 --- a/croutonjs/meetingMap/js/gmapsDelegate.js +++ b/croutonjs/meetingMap/js/gmapsDelegate.js @@ -15,15 +15,15 @@ function MapDelegate(in_config) { function isApiLoaded() { return gIsLoaded; } - async function loadApi(f, args) { - (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({ - key: config['api_key'], - v: "weekly", - }); - const { Map } = await google.maps.importLibrary("maps"); - const { AdvancedMarkerElement } = await google.maps.importLibrary("marker"); + function loadApi(f, args) { + var tag = document.createElement('script'); gIsLoaded = true; - croutonMap.apiLoadedCallback(); + if (typeof config['api_key'] === 'undefined') config['api_key'] = ""; + tag.src = "https://maps.googleapis.com/maps/api/js?key=" + config['api_key'] + "&callback=croutonMap.apiLoadedCallback"; + tag.defer = true; + tag.async = true; + var firstScriptTag = document.getElementsByTagName('script')[0]; + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); }; function createMap(inDiv, inCenter) { g_icon_image_single = new google.maps.MarkerImage ( config.BMLTPlugin_images+"/NAMarker.png", new google.maps.Size(23, 32), new google.maps.Point(0,0), new google.maps.Point(12, 32) ); @@ -382,6 +382,11 @@ function geoCallback( in_geocode_response ) { cb(e.latLng.lat(), e.latLng.lng()); }) }; + function afterInit(f) { + addListener('idle', function () { + f(); + }, true); + } function modalOn() {} function modalOff() {} this.createMap = createMap; @@ -410,6 +415,7 @@ function geoCallback( in_geocode_response ) { this.modalOn = modalOn; this.modalOff = modalOff; this.removeListener = removeListener; + this.afterInit = afterInit; } MapDelegate.prototype.createMap = null; MapDelegate.prototype.addListener = null; @@ -436,4 +442,5 @@ MapDelegate.prototype.removeClusterLayer = null; MapDelegate.prototype.clickSearch = null; MapDelegate.prototype.getGeocodeCenter = null; MapDelegate.prototype.modalOn = null; -MapDelegate.prototype.modalOff = null; \ No newline at end of file +MapDelegate.prototype.modalOff = null; +MapDelegate.prototype.afterInit = null; \ No newline at end of file diff --git a/croutonjs/meetingMap/js/meeting_map.js b/croutonjs/meetingMap/js/meeting_map.js index bcddf084..e2f20a88 100644 --- a/croutonjs/meetingMap/js/meeting_map.js +++ b/croutonjs/meetingMap/js/meeting_map.js @@ -206,6 +206,7 @@ function MeetingMap(inConfig) { let inDiv = document.getElementById(inDiv_id); loadMap(inDiv, menuContext, handlebarMapOptions,callback); loadAllMeetings(meetings_responseObject, fitBounds, true); + gDelegate.afterInit(()=>filterVisible(config.filter_visible)); }; function loadPopupMap(inDiv_id, meeting, handlebarMapOptions = null) { if (!gDelegate.isApiLoaded()) { diff --git a/croutonjs/meetingMap/js/osmDelegate.js b/croutonjs/meetingMap/js/osmDelegate.js index 0cf68205..add861c5 100644 --- a/croutonjs/meetingMap/js/osmDelegate.js +++ b/croutonjs/meetingMap/js/osmDelegate.js @@ -160,7 +160,7 @@ function MapDelegate(config) { return gMainMap.latLngToLayerPoint(L.latLng(lat,lng)); } function createMarker ( inCoords, ///< The long/lat for the marker. - multi, ///< The URI for the main icon + multi, ///< Flag if marker has multiple meetings in_html, ///< The info window HTML in_title, ///< The tooltip in_ids @@ -175,10 +175,10 @@ function MapDelegate(config) { if (typeof crouton != 'undefined') crouton.dayTabFromId(id); } var marker = L.marker(inCoords, {icon: in_main_icon, title: in_title}).bindPopup(in_html); + marker.isMulti = multi; if (gClusterLayer) gClusterLayer.addLayer(marker); else marker.addTo(gMainMap); marker.on('popupopen', function(e) { - marker.oldIcon = marker.getIcon(); marker.setIcon(g_icon_image_selected); gMainMap.on('zoomstart',function(){ marker.closePopup(); @@ -191,7 +191,7 @@ function MapDelegate(config) { }); }); marker.on('popupclose', function(e) { - marker.setIcon(marker.oldIcon); + marker.setIcon(marker.isMulti ? g_icon_image_multi : g_icon_image_single); jQuery(".bmlt-data-row > td").removeClass("rowHighlight"); }); gAllMarkers.push( {ids: in_ids, marker: marker} ); @@ -387,6 +387,9 @@ function addControl(div,pos,cb) { function modalOff() { if (gMainMap) gMainMap.dragging.enable() } + function afterInit(f) { + f(); + } function returnTrue() {return true;} this.createMap = createMap; this.addListener = addListener; @@ -413,6 +416,7 @@ function addControl(div,pos,cb) { this.getGeocodeCenter = getGeocodeCenter; this.modalOn = modalOn; this.modalOff = modalOff; + this.afterInit = afterInit; } MapDelegate.prototype.createMap = null; MapDelegate.prototype.addListener = null; @@ -439,3 +443,4 @@ MapDelegate.prototype.clickSearch = null; MapDelegate.prototype.getGeocodeCenter = null; MapDelegate.prototype.modalOn = null; MapDelegate.prototype.modalOff = null; +MapDelegate.prototype.afterInit = null; diff --git a/croutonjs/meetingMap/meeting_map.php b/croutonjs/meetingMap/meeting_map.php index 314b6679..511e0996 100644 --- a/croutonjs/meetingMap/meeting_map.php +++ b/croutonjs/meetingMap/meeting_map.php @@ -210,6 +210,7 @@ private function createJavascriptConfig($options) $ret['zoom'] = $options['zoom']; $ret['minZoom'] = $options['min_zoom']; $ret['maxZoom'] = $options['max_zoom']; + $ret['filter_visible'] = $options['filter_visible']; if (!empty($options['center_me'])) { $ret['centerMe'] = $options['center_me']; } @@ -296,7 +297,7 @@ public function adminSection()This allows a customization of the fields displayed when you click on a map icon. A list of available fields are - -.
+ +.0 = display meetings without tabs on dropdown filtering.
1 = display meetings with tabs on dropdown filtering.
Displaying tabs on filtering is useful when you have a large amount of results for each day on a dropdown selection.
+If the value is a number greater than 1, then if the number of meetings to be displayed is greater than this number, we will use the tabbed display.
embed = display map in a pane, and have it listen for filtering requests.
You can specify the maximum zoom level at which clustering is enabled, 15 is the default. This may be desirable with smaller data sets in which you don't want to cluster at all.
[bmlt_tabs show_map="1" max_zoom_level="7"]
-The Google API Key must be entered on the crouton settings page for this to work. You must have the 'Google Maps JavaScript API' enabled on your key. For more information on setting up and configuring a Google Maps API key check out this blog article https://bmlt.app/google-api-key/
-As an alternative to using google maps, you may install and activate the plugin "bmlt-meeting-map". In the settings for this plugin, you may select Open Street Maps, or any other standard conform map tile service. Upon activation, crouton companion maps will use this functionality, rather than the native google maps. +
Crouton allows the user to choose between a variety of map providers, including Google and OSM. A list of compatible providers is available here.
+If you choose Google as your provider, the Google API Key must be entered on the crouton settings page. You must have the 'Google Maps JavaScript API' enabled on your key. For more information on setting up and configuring a Google Maps API key check out this blog article https://bmlt.app/google-api-key/
+OSM does not require an API Key.
+With this parameter you can have crouton display a companion map of all the meetings.
+[bmlt_tabs filter_visible=1"]
+0 = the table includes all meetings, whether or not they are currently visible in the map (default)
+1 = the table includes only those meetings that are currently visible in the map
+The value may be modified "live" using the menu button in the map.
${error.message}
`); @@ -206,8 +205,8 @@ function MeetingMap(inConfig) { let inDiv = document.getElementById(inDiv_id); loadMap(inDiv, menuContext, handlebarMapOptions,callback); loadAllMeetings(meetings_responseObject, fitBounds, true); - config.filter_visible = config.filter_visible || config.goto || config.centerMe; - gDelegate.afterInit(()=>filterVisible(config.filter_visible)); + config.filter_visible = config.filter_visible; + if (!config.centerMe && !config.goto) gDelegate.afterInit(()=>filterVisible(config.filter_visible)); }; function loadPopupMap(inDiv_id, meeting, handlebarMapOptions = null) { if (!gDelegate.isApiLoaded()) { @@ -228,7 +227,7 @@ function MeetingMap(inConfig) { function filterFromCrouton(filter) { gMeetingIdsFromCrouton = filter; if (gAllMeetings) - searchResponseCallback(fitDuringFilter); + searchResponseCallback(fitDuringFilter && !listOnlyVisible); }; function nearMeSearch() { retrieveGeolocation().then(position => { @@ -311,7 +310,8 @@ function MeetingMap(inConfig) { navigator.geolocation.getCurrentPosition( function (position) { coords = {latitude: position.coords.latitude, longitude: position.coords.longitude}; - gDelegate.setViewToPosition(coords, filterMeetingsAndBounds); + filterVisible(false); + gDelegate.setViewToPosition(coords, filterMeetingsAndBounds, filterVisible); }, showGeocodingDialog ); @@ -319,7 +319,8 @@ function MeetingMap(inConfig) { showGeocodingDialog(); } } else if (config.goto) { - gDelegate.callGeocoder(config.goto, filterMeetingsAndBounds); + if (!config.centerMe && !config.goto) gDelegate.afterInit(()=>filterVisible(config.filter_visible)); + gDelegate.callGeocoder(config.goto, resetVisibleThenFilterMeetingsAndBounds); } } function createCityHash(allMeetings) { @@ -412,9 +413,9 @@ function MeetingMap(inConfig) { jQuery("#bmlt-map").css("display", "block"); } function resetVisibleThenFilterMeetingsAndBounds(bounds) { - const oldValue = filterVisible(false); + filterVisible(false); const ret = filterMeetingsAndBounds(bounds); - filterVisible(oldValue); + filterVisible(true); return ret; } function lookupLocation(fullscreen) { diff --git a/croutonjs/meetingMap/js/osmDelegate.js b/croutonjs/meetingMap/js/osmDelegate.js index add861c5..8f411837 100644 --- a/croutonjs/meetingMap/js/osmDelegate.js +++ b/croutonjs/meetingMap/js/osmDelegate.js @@ -84,16 +84,14 @@ function MapDelegate(config) { function setViewToPosition(position, filterMeetings, extra=null) { var latlng = L.latLng(position.latitude, position.longitude); gMainMap.flyTo(latlng); - gMainMap.on('moveend', function(ev) { - gMainMap.off('moveend'); + gMainMap.once('moveend', function(ev) { newZoom = getZoomAdjust(false, filterMeetings); if (gMainMap.getZoom() != newZoom) { gMainMap.setZoom(newZoom); - gMainMap.on('zoomend',function() { - gMainMap.off('zoomend'); + gMainMap.once('zoomend',function() { gMainMap.invalidateSize(); if (extra) { - gMainMap.on('load moveend', extra); + gMainMap.once('load moveend', extra); } }); } else { @@ -319,7 +317,7 @@ function addControl(div,pos,cb) { gMainMap.on('moveend', function(ev) { gMainMap.off('moveend'); gMainMap.setZoom(getZoomAdjust(true, filterMeetings)); - gMainMap.on('moveend',function() { + gMainMap.once('moveend',function() { gTileLayer.redraw(); }); }); diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index 39e3b784..cbb0bf06 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -528,6 +528,7 @@ function Crouton(config) { meetingCount = showingNow.length; addLive = function(id) {return id+"-live"}; } + self.showingNowCount = meetingCount; jQuery(addLive('#bmlt_tabs_meeting_count')).text(meetingCount); jQuery(addLive('#bmlt_tabs_group_count')).each(function(){ var filteredMeetings = self.meetingData; @@ -1373,7 +1374,8 @@ Crouton.prototype.render = function(doMeetingMap = false) { }); jQuery('#displayTypeButton_tablePages').on('click', function (e) { self.hidePage('#byfield_embeddedMapPage'); - self.showFilteredMeetingsAsTable(self.meetingData.length); + const knt = self.showingNowCount ? self.showingNowCount : self.meetingData.length; + self.showFilteredMeetingsAsTable(knt); }); jQuery('#filterButton_embeddedMapPage').on('click', function (e) { self.filteredView(e.target.attributes['data-field'].value, false); From 8a2ba7d35c5108b0eeca60c8935e76d03e797948 Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:10:32 +0200 Subject: [PATCH 06/11] small fix --- croutonjs/meetingMap/css/meeting_map.css | 3 ++- croutonjs/meetingMap/js/meeting_map.js | 1 - croutonjs/src/css/bmlt_tabs.css | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/croutonjs/meetingMap/css/meeting_map.css b/croutonjs/meetingMap/css/meeting_map.css index 74b49983..4993f7e4 100644 --- a/croutonjs/meetingMap/css/meeting_map.css +++ b/croutonjs/meetingMap/css/meeting_map.css @@ -474,7 +474,7 @@ div.bmlt_map_container_div button { } .menu-dropdown { display: none; -background-color: #EEEEEE; + background-color: #EEEEEE; color: #2d5c88; position: absolute; top: 45px; @@ -491,6 +491,7 @@ background-color: #EEEEEE; text-decoration: none; display: block; width: 100%; + background-color: #EEEEEE; } .leaflet-popup-content { margin: 0px 0px; diff --git a/croutonjs/meetingMap/js/meeting_map.js b/croutonjs/meetingMap/js/meeting_map.js index bae4d6d9..f3f01cb7 100644 --- a/croutonjs/meetingMap/js/meeting_map.js +++ b/croutonjs/meetingMap/js/meeting_map.js @@ -205,7 +205,6 @@ function MeetingMap(inConfig) { let inDiv = document.getElementById(inDiv_id); loadMap(inDiv, menuContext, handlebarMapOptions,callback); loadAllMeetings(meetings_responseObject, fitBounds, true); - config.filter_visible = config.filter_visible; if (!config.centerMe && !config.goto) gDelegate.afterInit(()=>filterVisible(config.filter_visible)); }; function loadPopupMap(inDiv_id, meeting, handlebarMapOptions = null) { diff --git a/croutonjs/src/css/bmlt_tabs.css b/croutonjs/src/css/bmlt_tabs.css index 8faa2996..b506701d 100644 --- a/croutonjs/src/css/bmlt_tabs.css +++ b/croutonjs/src/css/bmlt_tabs.css @@ -464,10 +464,10 @@ table.tablesaw { } .bmlt-map { - height: 400px; + height: 500px; } #byfield_embeddedMapPage{ - height: 400px; + height: 500px; } .bmlt-observer { font-size: 14px; @@ -632,13 +632,13 @@ table.tablesaw { direction: rtl; } #bmlt-header.bmlt-rtl { - text-align:right; + text-align:right; } #nav-days.bmlt-rtl { - float:right; + float:right; } #nav-days.bmlt-rtl li { - float:right; + float:right; } #bmlt-tabs .bmlt-rtl .bmlt-column1 { text-align: right; From a0be1b46015499a52d69e2f29c180a6a6af5af0b Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:37:40 +0200 Subject: [PATCH 07/11] small fix --- croutonjs/meetingMap/js/gmapsDelegate.js | 5 ++--- croutonjs/meetingMap/js/meeting_map.js | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/croutonjs/meetingMap/js/gmapsDelegate.js b/croutonjs/meetingMap/js/gmapsDelegate.js index ab3d1897..c01cddfa 100644 --- a/croutonjs/meetingMap/js/gmapsDelegate.js +++ b/croutonjs/meetingMap/js/gmapsDelegate.js @@ -382,9 +382,8 @@ function geoCallback( in_geocode_response ) { }) }; function afterInit(f) { - addListener('idle', function () { - f(); - }, true); + if (typeof gMainMap.getBounds() !== 'undefined') f(); + else addListener('idle', f, true); } function modalOn() {} function modalOff() {} diff --git a/croutonjs/meetingMap/js/meeting_map.js b/croutonjs/meetingMap/js/meeting_map.js index f3f01cb7..e1c46010 100644 --- a/croutonjs/meetingMap/js/meeting_map.js +++ b/croutonjs/meetingMap/js/meeting_map.js @@ -239,7 +239,7 @@ function MeetingMap(inConfig) { }); }; function clickSearch(e) { - croutonMap.showMap(); + croutonMap.showMap(false,false); gDelegate.clickSearch(e, function(lat,lng) { showThrobber(); crouton.searchByCoordinates(lat, lng, config.map_search.width); @@ -695,14 +695,14 @@ function MeetingMap(inConfig) { } gDelegate.invalidateSize(); } - function showMap(isModal=false) { + function showMap(isModal=false, fitBounds=true) { if (isModal && gModalDelegate) { gModalDelegate.invalidateSize(); return; } gDelegate.invalidateSize(); if (!gAllMeetings) return; - gDelegate.fitBounds( + if (fitBounds) gDelegate.fitBounds( ((gMeetingIdsFromCrouton) ? gAllMeetings.filter((m) => gMeetingIdsFromCrouton.includes(m.id_bigint)) : gAllMeetings) .reduce(function(a,m) {a.push([m.latitude, m.longitude]); return a;},[]) ); From 79ce828541b4058c8067dc179a9aa9a3ef6ab330 Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:49:26 +0200 Subject: [PATCH 08/11] start with embedded map when filtering by visibility --- croutonjs/meetingMap/js/meeting_map.js | 10 ++++++---- croutonjs/src/js/crouton-core.js | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/croutonjs/meetingMap/js/meeting_map.js b/croutonjs/meetingMap/js/meeting_map.js index e1c46010..8920e630 100644 --- a/croutonjs/meetingMap/js/meeting_map.js +++ b/croutonjs/meetingMap/js/meeting_map.js @@ -177,8 +177,10 @@ function MeetingMap(inConfig) { let dropdownContent = document.getElementById("map-menu-dropdown"); if (dropdownContent.style.display == "inline-block") { dropdownContent.style.display = "none"; - } else + } else { + jQuery("#filteringByVisibility").html(listOnlyVisible?'✔':''); dropdownContent.style.display = "inline-block"; + } }); [...controlDiv.getElementsByClassName('modal-close')].forEach((elem)=>elem.addEventListener('click', (e)=>closeModalWindow(e.target))); controlDiv.querySelector("#close_table").addEventListener('click', hideListView); @@ -205,7 +207,6 @@ function MeetingMap(inConfig) { let inDiv = document.getElementById(inDiv_id); loadMap(inDiv, menuContext, handlebarMapOptions,callback); loadAllMeetings(meetings_responseObject, fitBounds, true); - if (!config.centerMe && !config.goto) gDelegate.afterInit(()=>filterVisible(config.filter_visible)); }; function loadPopupMap(inDiv_id, meeting, handlebarMapOptions = null) { if (!gDelegate.isApiLoaded()) { @@ -304,6 +305,7 @@ function MeetingMap(inConfig) { } searchResponseCallback(); hideThrobber(); + if (config.filter_visible || config.centerMe || config.goto) crouton.forceShowMap(); if (config.centerMe) { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( @@ -317,9 +319,9 @@ function MeetingMap(inConfig) { } else if (fitAll) { showGeocodingDialog(); } - } else if (config.goto) { + } else { if (!config.centerMe && !config.goto) gDelegate.afterInit(()=>filterVisible(config.filter_visible)); - gDelegate.callGeocoder(config.goto, resetVisibleThenFilterMeetingsAndBounds); + if (config.goto) gDelegate.callGeocoder(config.goto, resetVisibleThenFilterMeetingsAndBounds); } } function createCityHash(allMeetings) { diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index cbb0bf06..8760829f 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -1434,6 +1434,11 @@ Crouton.prototype.render = function(doMeetingMap = false) { }, !doMeetingMap); }); }); + Crouton.prototype.forceShowMap = function() { + if (self.config.map_page && jQuery('#byfield_embeddedMapPage').hasClass('hide')) { + jQuery('#filterButton_embeddedMapPage').click(); + } + } }; From 99ce3319449d41cc29b093bd2391a2b0831c78f6 Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:02:20 +0200 Subject: [PATCH 09/11] reset filter also reset visibility filter --- croutonjs/meetingMap/js/meeting_map.js | 2 ++ croutonjs/src/js/crouton-core.js | 1 + 2 files changed, 3 insertions(+) diff --git a/croutonjs/meetingMap/js/meeting_map.js b/croutonjs/meetingMap/js/meeting_map.js index 8920e630..21ab0856 100644 --- a/croutonjs/meetingMap/js/meeting_map.js +++ b/croutonjs/meetingMap/js/meeting_map.js @@ -722,6 +722,7 @@ function MeetingMap(inConfig) { this.openModalWindow = openModalWindow; this.closeModalWindow = closeModalWindow; this.loadPopupMap = loadPopupMap; + this.filterVisible = filterVisible; }; MeetingMap.prototype.initialize = null; MeetingMap.prototype.showMap = null; @@ -733,3 +734,4 @@ MeetingMap.prototype.refreshMeetings = null; MeetingMap.prototype.openModalWindow = null; MeetingMap.prototype.closeModalWindow = null; MeetingMap.prototype.loadPopupMap = null; +MeetingMap.prototype.filterVisible = null; diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index 8760829f..24d7451c 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -451,6 +451,7 @@ function Crouton(config) { } } self.resetFilter = function () { + croutonMap.filterVisible(false); if (self.config.map_page) { if (self.filtering) croutonMap.fillMap(); jQuery('#displayTypeButton_tablePages').addClass('hide'); From b45817d428bc80da5ac997724b36d1035ddcfffd Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:29:58 +0200 Subject: [PATCH 10/11] do not adjust embedded map when switching from table --- croutonjs/src/js/crouton-core.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index 24d7451c..30a00852 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -1380,7 +1380,7 @@ Crouton.prototype.render = function(doMeetingMap = false) { }); jQuery('#filterButton_embeddedMapPage').on('click', function (e) { self.filteredView(e.target.attributes['data-field'].value, false); - croutonMap.showMap(); + croutonMap.showMap(false,false); }); jQuery('.custom-ul').on('click', 'a', function (event) { jQuery('.bmlt-page').each(function (index) { From c1ccbe5307c538042b38cce2a2aad47551458d9c Mon Sep 17 00:00:00 2001 From: otrok7 <50595291+otrok7@users.noreply.github.com> Date: Fri, 20 Sep 2024 14:13:14 +0200 Subject: [PATCH 11/11] some refactoring --- croutonjs/src/js/crouton-core.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index 30a00852..736a8ffb 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -326,7 +326,10 @@ function Crouton(config) { jQuery(id).removeClass("hide").addClass("show"); }; - self.showView = function (viewName) { + self.showView = function (viewName, resetFilters=true) { + if (resetFilters) { + self.resetFilter(); + } if (viewName === "byday") { self.byDayView(); } else if (viewName === "day" || viewName === "weekday") { @@ -339,7 +342,6 @@ function Crouton(config) { }; self.byDayView = function () { - self.resetFilter(); self.lowlightButton(".filterButton"); self.highlightButton("#day"); jQuery('.bmlt-page').each(function (index) { @@ -351,7 +353,6 @@ function Crouton(config) { }; self.dayView = function () { - self.resetFilter(); self.lowlightButton(".filterButton"); self.highlightButton("#day"); jQuery('.bmlt-page').each(function (index) { @@ -363,10 +364,7 @@ function Crouton(config) { }); }; - self.filteredView = function (field, resetFilters=true) { - if (resetFilters) { - self.resetFilter(); - } + self.filteredView = function (field) { self.lowlightButton("#day"); self.lowlightButton(".filterButton"); self.highlightButton("#filterButton_" + field); @@ -409,8 +407,6 @@ function Crouton(config) { }); if (!filteringDropdown) { self.filtering = false; - if (croutonMap) croutonMap.fillMap(); - return; } var showingNow = []; jQuery(".bmlt-data-row").not(".hide").each(function (index, value) { @@ -1745,7 +1741,7 @@ Crouton.prototype.simulateFilterDropdown = function() { }); self.filteredPage(); if (!self.filtering && !self.config.map_page) - self.showView(self.config['view_by'] === 'byday' ? 'byday' : 'day'); + self.showView(self.config['view_by'] === 'byday' ? 'byday' : 'day', false); } Crouton.prototype.getAdjustedDateTime = function(meeting_day, meeting_time, meeting_time_zone) { var timeZoneAware = this.config['auto_tz_adjust'] === true || this.config['auto_tz_adjust'] === "true";