From 0dae1684d1d5539a0d634adc39f2ed4e3e973f9b Mon Sep 17 00:00:00 2001 From: Eloi Zalczer Date: Tue, 18 Jun 2024 18:04:21 +0200 Subject: [PATCH] Added marker highlighting when hovering table. --- src/components/RestaurantsMap.vue | 40 +++++++++++++++++++++++++---- src/components/RestaurantsTable.vue | 35 +++++++++++++++++++++++-- src/models/restaurant.ts | 1 + src/views/ListView.vue | 14 ++++++++-- 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/src/components/RestaurantsMap.vue b/src/components/RestaurantsMap.vue index c834788..d23ae57 100644 --- a/src/components/RestaurantsMap.vue +++ b/src/components/RestaurantsMap.vue @@ -7,36 +7,66 @@ import LatLng from "../models/map"; import { storeToRefs } from "pinia"; import { useRestaurantsStore } from "../stores/restaurants"; -const initialMap = ref(null); +const map = ref(null); const { restaurants } = storeToRefs(useRestaurantsStore()); +const props = defineProps({ + highlighted: { type: String }, +}); + const emit = defineEmits({ clicked: (latlng: LatLng) => true, }); +const markers = ref>(new Map()); + onMounted(() => { - initialMap.value = L.map("map").setView([48.8363012, 2.240709935], 14); + map.value = L.map("map").setView([48.8363012, 2.240709935], 14); L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 19, attribution: '© OpenStreetMap', - }).addTo(initialMap.value); + }).addTo(map.value); - initialMap.value!.on("click", function (e) { + map.value!.on("click", function (e) { emit("clicked", e.latlng); }); watch( () => restaurants.value, async (newval, oldval) => { + markers.value.forEach((marker) => marker.remove()); + markers.value.clear(); restaurants.value?.forEach((restaurant) => { const marker = L.marker({ lat: restaurant.latitude, lng: restaurant.longitude }); marker.bindPopup(`

${restaurant.name}

`); - marker.addTo(initialMap.value); + marker.addTo(map.value); + markers.value.set(restaurant.id, marker); }); }, { immediate: true } ); + + watch( + () => props.highlighted, + (newval, oldval) => { + console.log(markers.value); + if (oldval != null) { + var old = markers.value.get(oldval); + console.log("old", old, oldval); + if (old.isPopupOpen()) { + old.closePopup(); + } + } + if (newval != null) { + var marker = markers.value.get(newval); + console.log("new", marker, newval); + if (!marker.isPopupOpen()) { + marker.openPopup(); + } + } + } + ); }); diff --git a/src/components/RestaurantsTable.vue b/src/components/RestaurantsTable.vue index ddaaf59..d548e1c 100644 --- a/src/components/RestaurantsTable.vue +++ b/src/components/RestaurantsTable.vue @@ -6,11 +6,12 @@ import DataTablesCore from "datatables.net"; import "datatables.net-select"; import { PropType, ref } from "vue"; import RatingField from "./RatingField.vue"; +import Restaurant from "../models/restaurant"; DataTable.use(DataTablesCore); const props = defineProps({ - data: { type: Array as PropType }, + data: { type: Array as PropType }, }); const columns = [ @@ -31,7 +32,35 @@ function deselectAll() { table.value?.dt.rows({ selected: true }).deselect(); } -const emit = defineEmits(["restaurantSelected"]); +const emit = defineEmits({ + restaurantSelected: (restaurant: Object) => true, + restaurantHovered: (restaurant: Object | null) => true, +}); + +const hovered = ref(); + +function onMouseOver(e) { + const row = e.target?._DT_CellIndex?.row; + console.log("row", row); + + if (row !== undefined && props.data !== undefined) { + if (hovered.value != props.data[row]) { + emit("restaurantHovered", props.data[row].id); + } + hovered.value = props.data[row]; + } else { + if (hovered.value !== null) { + emit("restaurantHovered", null); + console.log("hovered"); + } + hovered.value = null; + } +} + +function onMouseLeave() { + emit("restaurantHovered", null); + hovered.value = null; +} defineExpose({ deselectAll }); @@ -40,6 +69,8 @@ defineExpose({ deselectAll });
- +
- +