Added marker highlighting when hovering table.
parent
fa49ed91a8
commit
0dae1684d1
|
|
@ -7,36 +7,66 @@ import LatLng from "../models/map";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { useRestaurantsStore } from "../stores/restaurants";
|
import { useRestaurantsStore } from "../stores/restaurants";
|
||||||
|
|
||||||
const initialMap = ref<L.Map | null>(null);
|
const map = ref<L.Map | null>(null);
|
||||||
|
|
||||||
const { restaurants } = storeToRefs(useRestaurantsStore());
|
const { restaurants } = storeToRefs(useRestaurantsStore());
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
highlighted: { type: String },
|
||||||
|
});
|
||||||
|
|
||||||
const emit = defineEmits({
|
const emit = defineEmits({
|
||||||
clicked: (latlng: LatLng) => true,
|
clicked: (latlng: LatLng) => true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const markers = ref<Map<string, L.Marker>>(new Map());
|
||||||
|
|
||||||
onMounted(() => {
|
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", {
|
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||||
maxZoom: 19,
|
maxZoom: 19,
|
||||||
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||||||
}).addTo(initialMap.value);
|
}).addTo(map.value);
|
||||||
|
|
||||||
initialMap.value!.on("click", function (e) {
|
map.value!.on("click", function (e) {
|
||||||
emit("clicked", e.latlng);
|
emit("clicked", e.latlng);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => restaurants.value,
|
() => restaurants.value,
|
||||||
async (newval, oldval) => {
|
async (newval, oldval) => {
|
||||||
|
markers.value.forEach((marker) => marker.remove());
|
||||||
|
markers.value.clear();
|
||||||
restaurants.value?.forEach((restaurant) => {
|
restaurants.value?.forEach((restaurant) => {
|
||||||
const marker = L.marker({ lat: restaurant.latitude, lng: restaurant.longitude });
|
const marker = L.marker({ lat: restaurant.latitude, lng: restaurant.longitude });
|
||||||
marker.bindPopup(`<p>${restaurant.name}</p>`);
|
marker.bindPopup(`<p>${restaurant.name}</p>`);
|
||||||
marker.addTo(initialMap.value);
|
marker.addTo(map.value);
|
||||||
|
markers.value.set(restaurant.id, marker);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,12 @@ import DataTablesCore from "datatables.net";
|
||||||
import "datatables.net-select";
|
import "datatables.net-select";
|
||||||
import { PropType, ref } from "vue";
|
import { PropType, ref } from "vue";
|
||||||
import RatingField from "./RatingField.vue";
|
import RatingField from "./RatingField.vue";
|
||||||
|
import Restaurant from "../models/restaurant";
|
||||||
|
|
||||||
DataTable.use(DataTablesCore);
|
DataTable.use(DataTablesCore);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Array as PropType<Object[]> },
|
data: { type: Array as PropType<Restaurant[]> },
|
||||||
});
|
});
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
|
|
@ -31,7 +32,35 @@ function deselectAll() {
|
||||||
table.value?.dt.rows({ selected: true }).deselect();
|
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<Restaurant | null>();
|
||||||
|
|
||||||
|
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 });
|
defineExpose({ deselectAll });
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -40,6 +69,8 @@ defineExpose({ deselectAll });
|
||||||
<DataTable
|
<DataTable
|
||||||
class="table"
|
class="table"
|
||||||
ref="table"
|
ref="table"
|
||||||
|
@mouseover="onMouseOver"
|
||||||
|
@mouseleave="onMouseLeave"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="props.data"
|
:data="props.data"
|
||||||
:options="{
|
:options="{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
export default interface Restaurant {
|
export default interface Restaurant {
|
||||||
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
price: string;
|
price: string;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ const drawer = ref<typeof ReviewsDrawer>();
|
||||||
const table = ref<typeof RestaurantsTable>();
|
const table = ref<typeof RestaurantsTable>();
|
||||||
|
|
||||||
const selectedRestaurant = ref<Object>();
|
const selectedRestaurant = ref<Object>();
|
||||||
|
const highlightedRestaurant = ref<string>();
|
||||||
|
|
||||||
const { restaurants } = storeToRefs(useRestaurantsStore());
|
const { restaurants } = storeToRefs(useRestaurantsStore());
|
||||||
|
|
||||||
|
|
@ -22,6 +23,10 @@ function onRestaurantSelected(restaurant: Object) {
|
||||||
drawer.value?.open();
|
drawer.value?.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onRestaurantHovered(id: string) {
|
||||||
|
highlightedRestaurant.value = id;
|
||||||
|
}
|
||||||
|
|
||||||
function onDrawerClosed() {
|
function onDrawerClosed() {
|
||||||
console.log("closed");
|
console.log("closed");
|
||||||
table.value?.deselectAll();
|
table.value?.deselectAll();
|
||||||
|
|
@ -31,10 +36,15 @@ function onDrawerClosed() {
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col-reverse sm:flex-row">
|
<div class="flex flex-col-reverse sm:flex-row">
|
||||||
<div class="w-full flex-1">
|
<div class="w-full flex-1">
|
||||||
<RestaurantsTable ref="table" @restaurant-selected="onRestaurantSelected" :data="restaurants" />
|
<RestaurantsTable
|
||||||
|
ref="table"
|
||||||
|
@restaurant-selected="onRestaurantSelected"
|
||||||
|
@restaurant-hovered="onRestaurantHovered"
|
||||||
|
:data="restaurants"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 h-3/6 lg:h-full">
|
<div class="flex-1 h-3/6 lg:h-full">
|
||||||
<RestaurantsMap />
|
<RestaurantsMap :highlighted="highlightedRestaurant" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue