First of all, thanks for the great plugin!
Please excuse me if this is a Vue.js question rather than specific to this plugin. I'm new to Vue.js and might just be missing something...
I have a map with many markers on it, and would like to react to the user clicking or hovering over one of the markers. I used v-on:l-mouserover and v-on:l-click to get an event out of it. The problem is that I can't then access the marker component with its props, only the Leaflet object as target. I would like to be able to access the props as they tell me the identity of the marker in question. I tried using a mixin with the v-marker component to be able to use this, but I didn't manage to do that.
I also tried to create a custom component for the marker, that includes the <v-marker> component within its template, but no marker was rendered. Should this be possible? (i.e. a custom component for the marker that adds the features I need and include it within a <v-map> component?)
Is there a better way?
Thanks for any help you can give!
A solution I found for now, which perhaps might be integrated to the plugin, is to modify eventBinder so that instead of only emitting the event ev, it also sends the element vueElement inside the vueElement.$emit. Then I can access the element from my callback (which is a method in the component that adds the map and markers.
Does this approach make sense?
Hi @omrihar,
Your approach seems to make sense to me but I'm not sure what kind of property you are trying to access, all Markers properties are also available on the Leaflet object.
Can you give a more specific example of what you try to achieve. A JSFiddle example would be perfect (you can easily fork this one).
Cheers,
Micka毛l
Hi @KoRiGaN,
The actual application is a bit complex, but as a simple example consider the following setup:
I have a list of contacts, each of which has several fields of data about them. For example:
contact_person = {
name: 'Contact Name',
address: {
complete_address: '...',
position: [lng, lat]
},
phone_number: '+49.....',
email: '[email protected]'
}
I display all these contacts on the map as markers, and once a marker is clicked, I open a drawer that displays all the metadata and allows to perform actions (e.g. call, e-mail, add to todo list, etc..). In the real app, selecting the marker marks the contact person as the current person in the Vuex store, but that's not necessary to understand the use-case, I guess.
What I do now is that I copied the Marker component from your library and added a prop called 'data' that stores the contact_person object above, and then when clicked I use that data to display the drawer. Like I wrote above, I also changed the eventBinder to include a reference to the VueComponent of the marker, so I can just do VueComponent.data to get the data I need. I think the best approach would have been to be able to extend the Marker component, but I don't know if Vue.js supports that.
Is this illuminating enough, or would you like me to create a fiddle as well?
Thanks!
Omri
Hi @omrihar,
Here is an example of how I would do it.
No modification of Vue2Leaflet required. Just send you contact as a parameter of the event handler.
Hope this helps!
Micka毛l
Hi @KoRiGaN,
thanks! Of course! I just didn't think about that. This will indeed solve the problem... As I mentioned, I'm still learning the ropes in Vue.js so sometimes I don't think of the obvious.
I have another question though, which might be a bit more complicated: is there a way to bind the icon of a marker to the state of some property? I would like to have, for example, one icon for the 'active' contact, i.e. the one whose details are currently being displayed, and a different icon for the others. Ideally, this will all use the Vue.js reactivity system.
Thanks again!
Omri
Hi @omrihar,
You can find a working example for your last question in the issue #95.
Micka毛l
@KoRiGaN what if i want to do it the other way around? say i have a list of those same contacts and when i click the cell/row i want the marker popup to activate, so as to locate them in the map?
i ended up adding a ref to each marker and using a shared identifier to open it programmatically like so:
this.$refs[identifier][0].mapObject.openPopup()
note the [0] because markers are in a v-for and the $refs returns an array there
i ended up adding a
refto each marker and using a shared identifier to open it programmatically like so:this.$refs[identifier][0].mapObject.openPopup()note the
[0]because markers are in av-forand the$refsreturns an array there
Hey there 馃憢
After some time of research, I ended doing this also.
I thought I could access my marker through the :key or LMarker but didn't find a way to do so either on the doc or internet.
So I put a ref to my marker loop (let's say around 14 items) and could access it through what you said:
<l-marker
v-for="(marker, index) in markers"
:key="index"
ref="myMarker"
:lat-lng="latLng(marker.gps.lat, marker.gps.long)"
>
<l-popup></l-popup>
</l-marker>
And to open the popup:
this.$refs.myMarker[index of the one I want to select].mapObject.openPopup()
Wish there was a way to do the same by selecting LMarker with the proper :key.
Anyway, nice ! 馃憤
Most helpful comment
i ended up adding a
refto each marker and using a shared identifier to open it programmatically like so:this.$refs[identifier][0].mapObject.openPopup()note the
[0]because markers are in av-forand the$refsreturns an array there