diff --git a/CHANGELOG.md b/CHANGELOG.md
index 07621c0cc..31197ba84 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,7 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Breaking change:** Updated checkbox and radio component according to adjustments from design (Figma), both now have label options, correct spacing and correct font size and weight. Also changed naming of modifiers to be more consistent with other components.
- **Breaking change:** Create a helper for animations and refactor accordion component accordingly. You need to replace the class 'ods-accordion--animate' with 'ods-animation ods-animation--rotate'.
- **Breaking change:** Update the size of text in the banner. There are changes on the css classes in the markup of headings and paragrafs that need to be replaced.
-
+- **Breaking change:** Moved geoJSON fetching from component to a per-vue-instance setup.
### Fixed
@@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed spacing around links and buttons in portrait card on all breakpoints.
- Fixed links on portrait cards to improve screen reader capabilities.
- Replaced deprecated ods-icon--space-right classes with ods-margin-right-1 on contactbox, portrait card and status card
+- Fixed an issue causing multiple map-popups to open and overlay each other.
### Removed
diff --git a/src/components/map/geoJsonUtils.js b/src/components/map/geoJsonUtils.js
new file mode 100644
index 000000000..0bea1ad02
--- /dev/null
+++ b/src/components/map/geoJsonUtils.js
@@ -0,0 +1,7 @@
+const fetchGeoJsonData = async (url) => {
+ const response = await fetch(url);
+ const jsonData = await response.json();
+ return jsonData;
+};
+
+export default fetchGeoJsonData;
diff --git a/src/components/map/map.html b/src/components/map/map.html
index f98060b34..d15d91bcd 100644
--- a/src/components/map/map.html
+++ b/src/components/map/map.html
@@ -102,7 +102,7 @@
Highlight a polygon
Single marker with automatic popup and ratio for different breakpoints
@@ -110,7 +110,7 @@ Single marker with automatic popup and ra
Markers with clustering
@@ -118,7 +118,7 @@ Markers with clustering
Various features, with highlighted polygon
@@ -133,7 +133,7 @@ Single marker with automatic popup
@@ -141,7 +141,7 @@
Markers with clustering
@@ -149,7 +149,7 @@
Various features, with highlighted polygo
@@ -165,7 +165,7 @@
Reactivity geoJson
@@ -181,11 +181,13 @@
Load map later
diff --git a/src/components/map/map.js b/src/components/map/map.js
index 30189506f..33eff5d51 100644
--- a/src/components/map/map.js
+++ b/src/components/map/map.js
@@ -1,5 +1,6 @@
import { createApp } from 'vue';
import OdsMap from './map.vue';
+import fetchGeoJsonData from './geoJsonUtils';
document.addEventListener('DOMContentLoaded', () => {
const mapElement = document.getElementById('ods-map');
@@ -20,20 +21,51 @@ document.addEventListener('DOMContentLoaded', () => {
});
app1.mount(mapElement);
}
+
if (mapElement2) {
const app2 = createApp({
name: 'OdsMapApp2',
components: { OdsMap },
+ data() {
+ return {
+ geoJsonData: null,
+ };
+ },
+ async mounted() {
+ setTimeout(async () => {
+ try {
+ this.geoJsonData = await fetchGeoJsonData('https://ukeweb-public.s3.dualstack.eu-central-1.amazonaws.com/map/data/kindergarten-with-events.geojson');
+ } catch (error) {
+ throw new Error('Error fetching GeoJSON data:', error);
+ }
+ }, 15000);
+ },
});
app2.mount(mapElement2);
}
+
if (mapElement3) {
const app3 = createApp({
name: 'OdsMapApp3',
components: { OdsMap },
+ data() {
+ return {
+ geoJsonData: null,
+ };
+ },
+ async mounted() {
+ setTimeout(async () => {
+ try {
+ this.geoJsonData = await fetchGeoJsonData('https://ukeweb-public.s3.eu-central-1.amazonaws.com/map/data/featurecollection-with-popups-and-multi-variants.geojson');
+ } catch (error) {
+ throw new Error('Error fetching GeoJSON data:', error);
+ }
+ }, 15000);
+ },
});
app3.mount(mapElement3);
}
+
if (mapElement4) {
const app4 = createApp({
name: 'OdsMapApp4',
@@ -57,6 +89,20 @@ document.addEventListener('DOMContentLoaded', () => {
const app5 = createApp({
name: 'OdsMapApp5',
components: { OdsMap },
+ data() {
+ return {
+ geoJsonData: null,
+ };
+ },
+ async mounted() {
+ setTimeout(async () => {
+ try {
+ this.geoJsonData = await fetchGeoJsonData('https://ukeweb-public.s3.dualstack.eu-central-1.amazonaws.com/map/data/kindergarten-with-events.geojson');
+ } catch (error) {
+ throw new Error('Error fetching GeoJSON data:', error);
+ }
+ }, 15000);
+ },
});
app5.mount(mapElement5);
}
@@ -65,6 +111,20 @@ document.addEventListener('DOMContentLoaded', () => {
const app6 = createApp({
name: 'OdsMapApp6',
components: { OdsMap },
+ data() {
+ return {
+ geoJsonData: null,
+ };
+ },
+ async mounted() {
+ setTimeout(async () => {
+ try {
+ this.geoJsonData = await fetchGeoJsonData('https://ukeweb-public.s3.eu-central-1.amazonaws.com/map/data/featurecollection-with-popups-and-multi-variants.geojson');
+ } catch (error) {
+ throw new Error('Error fetching GeoJSON data:', error);
+ }
+ }, 15000);
+ },
});
app6.mount(mapElement6);
}
@@ -90,13 +150,25 @@ document.addEventListener('DOMContentLoaded', () => {
const app8 = createApp({
name: 'OdsMapApp8',
components: { OdsMap },
- data: () => ({
- geoJson: 'https://ukeweb-public.s3.dualstack.eu-central-1.amazonaws.com/map/data/kindergarten-with-events-ods.geojson',
- }),
-
- mounted() {
- setTimeout(() => {
- this.geoJson = 'https://ukeweb-public.s3.dualstack.eu-central-1.amazonaws.com/map/data/featurecollection-with-popups.geojson';
+ data() {
+ return {
+ geoJsonData: null,
+ };
+ },
+ async created() {
+ try {
+ this.geoJsonData = await fetchGeoJsonData('https://ukeweb-public.s3.dualstack.eu-central-1.amazonaws.com/map/data/kindergarten-with-events-ods.geojson');
+ } catch (error) {
+ throw new Error('Error fetching GeoJSON data:', error);
+ }
+ },
+ async mounted() {
+ setTimeout(async () => {
+ try {
+ this.geoJsonData = await fetchGeoJsonData('https://ukeweb-public.s3.eu-central-1.amazonaws.com/map/data/featurecollection-with-popups-and-multi-variants.geojson');
+ } catch (error) {
+ throw new Error('Error fetching GeoJSON data:', error);
+ }
}, 15000);
},
});
diff --git a/src/components/map/map.vue b/src/components/map/map.vue
index 736211af8..fdd89695e 100644
--- a/src/components/map/map.vue
+++ b/src/components/map/map.vue
@@ -46,8 +46,8 @@ export default {
}),
},
geoJson: {
- // Can't set type, as MapLibre accepts both an URL and an object
- default: null,
+ type: Object,
+ default: () => ({}),
},
points: {
type: Array,
@@ -77,6 +77,7 @@ export default {
mapLoaded: false,
error: false,
technicalErrorText: '',
+ popups: [],
}),
computed: {
@@ -123,19 +124,15 @@ export default {
pointsGeoJson: {
deep: true,
handler() {
- if (this.loadMap === true) {
- this.clearMapAndData();
- this.populateMap();
- }
+ this.clearMapAndData();
+ this.populateMap();
},
},
geoJson: {
deep: true,
handler() {
- if (this.loadMap === true) {
- this.clearMapAndData();
- this.populateMap();
- }
+ this.clearMapAndData();
+ this.populateMap();
},
},
state: {
@@ -158,21 +155,13 @@ export default {
mapLoad() {
if (!this.mapLoaded) {
this.mapLoaded = true;
- if (typeof this.geoJson === 'string') {
- fetch(this.geoJson)
- .then((response) => response.json())
- .then((data) => {
- this.$_createMapObject(data);
- });
- } else {
- this.$_createMapObject(this.geoJson);
- }
+ this.$_createMapObject(this.geoJson);
}
},
populateMap() {
// Will only populate if map is ready (load event done)
if (this.mapReady) {
- if (this.pointsGeoJson !== null) {
+ if (this.pointsGeoJson?.features?.length > 0) {
this.mapObject.addSource('points', {
type: 'geojson',
data: this.pointsGeoJson,
@@ -185,29 +174,17 @@ export default {
}
}
- if (this.geoJson !== null) {
+ // Check if there's valid geoJson data for non-clustered or clustered points
+ if (this.geoJson && Object.keys(this.geoJson).length > 0) {
if (!this.clusteredPoints) {
- if (typeof this.geoJson === 'string') {
- fetch(this.geoJson)
- .then((response) => response.json())
- .then((data) => {
- this.$_addGeoJsonToMap(data);
- });
- } else {
- this.$_addGeoJsonToMap(this.geoJson);
- }
- } else if (typeof this.geoJson === 'string') {
- fetch(this.geoJson)
- .then((response) => response.json())
- .then((data) => {
- this.$_splitClusterDataAndAddToMap(data);
- });
+ this.$_addGeoJsonToMap(this.geoJson);
} else {
this.$_splitClusterDataAndAddToMap(this.geoJson);
}
}
}
},
+
clearMapAndData() {
if (this.lastDisplayedPopup !== null) {
this.lastDisplayedPopup.remove();
@@ -361,7 +338,7 @@ export default {
}
this.mapObject.addSource('geoJson', {
type: 'geojson',
- data: geoJson,
+ data: this.geoJson,
});
this.dataSourceIds.push('geoJson');
@@ -631,6 +608,10 @@ export default {
},
// Private/protected method
$_addPopupToMap(lngLat, feature) {
+ if (this.lastDisplayedPopup) {
+ this.lastDisplayedPopup.remove();
+ }
+
const html = this.$_getPopupHtml(feature);
if (typeof html === 'string') {
const popup = new maplibregl.Popup({ className: 'ods-map__popup' }).setLngLat(lngLat).setHTML(html);