I want to openPopup behind search marker
maneewihok opened this issue · 14 comments
<div v-for="marker in referOjectOptions" :key="marker.id">
<l-marker :lat-lng="[marker.lat, marker.lon]">
<l-popup>
{{ marker.projectNameTH }}
</l-popup>
</l-marker>
</div>
methods: {
search(event) {
const item = this.referOjectInput;
if (!item.lat && !item.log) {
return;
}
this.$refs.leafmap.mapObject.flyToBounds([[item.lat, item.lon]]);
// popup[item]Open ?
},
@maneewihok is there a reason you have that div
around each marker? If you instead had
<l-marker v-for="marker in referOjectOptions" :key="marker.id" ref="mapMarkers">
<l-popup>
{{ marker.projectNameTH }}
</l-popup>
</l-marker>
then I think you should be able to use something along the lines of this.$refs.mapMarkers[index].openPopup()
, where you just have to map the item
you already have to the correct index
value for it.
@mikeu i try
for (let index = 0; index < item.length; index++) {
this.$refs.mapMarkers[index].openPopup();
}
it's not work.
@maneewihok sorry, I forgot to include that you have to reference the Leaflet object to open the popup on. Does it work with this.$refs.mapMarkers[index].mapObject.openPopup()
?
@mikeu It doesn't open T^T
<l-map ref="leafmap" v-if="showMap" :zoom="zoom" :center="center">
<v-tilelayer :url="url" :attribution="attribution"></v-tilelayer>
<v-marker-cluster v-if="geoJsonLoaded" :options="clusterOptions">
<l-marker
ref="mapMarkers"
:lat-lng="[markers.lat, markers.lon]"
v-for="markers in referObjectOptions"
:key="markers.id"
>
<l-popup>
{{ markers.projectNameTH }}
</l-popup>
<l-tooltip>
{{ markers.projectNameTH }}
</l-tooltip>
</l-marker>
</v-marker-cluster>
</l-map>
methods: {
search(event) {
const item = this.referObjectInput;
if (!item.lat && !item.log) {
return;
}
this.$refs.leafmap.mapObject.flyToBounds([[item.lat, item.lon]]);
this.openPopups();
},
openPopups() {
const item = this.referObjectInput;
for (let index = 0; index < item.length; index++) {
this.$refs.mapMarkers[index].mapObject.openPopup();
// this.$refs.mapMarkers[index].mapObject.openPopup();
}
},
@maneewihok why are you opening every popup on the map in turn? By default, when one popup is opened, Leaflet closes every other popup so that there is only ever one shown at a time. If the last one in your array is not the one you zoomed to, then maybe the popup is opening, but only a different one not in the current view ends up being visible...?
@maneewihok sorry, I am still not clear why you are opening every popup on the map each time the search
method is called. That example only shows a single popup at a time, for only the one search result selected.
Perhaps you want to do something like add :id="`marker-${markers.id}`"
to your l-marker
, and then find the appropriate element and open it:
openPopup() {
const item = this.referObjectInput;
const markerToOpen = this.$refs.mapMarkers.find(m => m.$el.id === `marker-${item.id}`);
if (markerToOpen) {
markerToOpen.mapObject.openPopup();
}
}
Note that this is untested code, and as I don't have any indication of how your referObjectInput
object or the elements in your referObjectOptions
array are structured, there might be a better approach overall. But based on what you've shown me, I think something like this should at least work.
Either way, I do not think that this represents any bug or problem with the vue2-leaflet library so I'll close the issue at this point.
And @maneewihok , if you still can't get this working then I'm happy to try to help you find a solution, even with the issue closed. Hopefully you are nearly there though!
@mikeu Thank you, but the default popup is off.
Thanks for source code
Now, when it zooms to the marker You'll need to press the search button again before the pop-up will open.
What do i have to do
<l-marker
ref="mapMarkers"
:id="`marker-${markers.id}`"
:lat-lng="[markers.lat, markers.lon]"
v-for="markers in referObjectOptions"
:key="markers.id"
>
<l-popup>
{{ markers.projectNameTH }}
</l-popup>
methods: {
search(event) {
const item = this.referObjectInput;
const markerToOpen = this.$refs.mapMarkers.find(
m => m.$el.id === `marker-${item.id}`
);
if (!item.lat && !item.log) {
return;
}
this.$refs.leafmap.mapObject.flyToBounds([[item.lat, item.lon]]);
markerToOpen.mapObject.openPopup();
https://drive.google.com/file/d/1F1y7GX39qxcvHLmbS09T4mhf-aX-vPix/view?usp=sharing
@maneewihok I watched that video, I see what you mean about having to click again. I can't see anything in the portion of your code you've shared that might explain that though. It could be all sorts of things, such as if this.referObjectInput
is somehow not set correctly after the first click.
Here is a codesandbox demo that shows a simple version of what I think you are trying to accomplish, working correctly for me: https://codesandbox.io/s/marker-array-popup-0lkue?file=/src/App.vue
I hope that helps. Perhaps if you are still having trouble, you can create a demo yourself that reproduces the error. At this point, I suspect that you have a bug somewhere else in your application, but it is very hard to debug or guess at the cause without knowing what the code is doing.
Mr. @mikeu i have 1 more question
Now you can zoom in and open the popup.
But if <v-marker-cluster>
is inserted when zooming, the pop-up will not appear Need to press repeatedly. Why?
<v-marker-cluster>
<l-marker
ref="mapMarkers"
v-for="obj in referenceObjects"
:key="obj.id"
:id="`mark-${obj.id}`"
:lat-lng="[obj.lat, obj.lon]"
>
<l-popup>{{ obj.projectNameTH }}</l-popup>
</l-marker>
</v-marker-cluster>
search(event) {
const item = this.selectedObject;
if (!item || !item.lat || !item.lon) {
return;
}
this.$refs.map.mapObject.flyToBounds([[item.lat, item.lon]]);
const markerToOpen = this.$refs.mapMarkers.find(m => {
return m.$el.id === `mark-${item.id}`;
});
markerToOpen.mapObject.openPopup();
},
If there is no cluster, the pop-up is normally open.
@maneewihok I believe the problem is that when the search is performed, the marker that you want to open the popup on is hidden inside a cluster. So trying to open the popup for it at that moment does nothing, because it is not visible.
To get around this, you can store the map marker object when it is found in the search
method, and then respond to the @zoomend
event on the map to open it then. There is one final trick too, that the marker doesn't actually appear until just after the zoom event has been fired, so you actually have to show the popup in the next Vue tick.
Here's a working example, with the changes outlined below: https://codesandbox.io/s/marker-array-popup-cluster-0lkue?file=/src/App.vue
<l-map @zoomend="showZoomedPopup" ...>
methods: {
search() {
// ...
const markerToOpen = this.$refs.mapMarkers.find(...);
this.zoomMarker = markerToOpen.mapObject; // <--- CHANGED: Save reference to map object
},
showZoomedPopup() {
// If there is a saved map object after the zoom finishes, open its popup and unset it on the next tick
if (this.zoomMarker) {
this.$nextTick(() => {
this.zoomMarker.openPopup();
this.zoomMarker = undefined;
});
}
}
}
Because the marker is invisible on the map until the zoom has finished, I am not sure if there is any way to open it earlier while the animation is happening. For that I think you would have to ask at the vue2-leaflet-markerclust repo about how to force one marker to be shown outside of the calculated clusters.
@mikeu thank you for support <3