26

when a marker is clicked, I need to execute some code that finds the id corresponding to the marker being clicked , retrieves data from backend API, then adds the newly retrieved data to the content of the popup that will open.

The only way that is able to listen to a click event on the marker is

map.on('popupopen', function(e){
    // How to retrieve marker?
    // eg: Assign an id on creation, retrieve it now during popupopen
};)

How can I find out which marker this is? Is it possible to add an id attribute to each marker, then retrieve this id during the popupopen event?

Nyxynyx
  • 61,411
  • 155
  • 482
  • 830
  • http://leaflet.cloudmade.com/reference.html#marker A `L.Marker` is placed on the map: `marker.addTo(map)`. I am able to pass an `id` value to each individual `marker` object. How should this be done, and how can I retrieve this `id` later during a `popupopen` event? – Nyxynyx Oct 03 '12 at 03:36
  • When creating markers, I do something like `var marker = new L.marker( new L.LatLng( lat, lng ));` Then `marker.setContent(content).addTo(map)`. – Nyxynyx Oct 03 '12 at 04:14

6 Answers6

39

The event object contains a "popup" attribute that has a private attribute called "_source" which is the object that the popup is bound to (i.e. the marker). Since _source is supposed to be private this doesn't seem like the right way but I'm not sure how else to do it.

map.on('popupopen', function(e) {
  var marker = e.popup._source;
});
InPursuit
  • 3,245
  • 24
  • 20
  • I'm getting `undefined` on `e.popup._source` when opening a popup that was generated by a `L.geoJson()` call. Any clues? – Nighto Jul 15 '15 at 02:41
  • My **dirty** solution on the moment was to include a `
    ` inside the popup content on `onEachFeature` and then looking it up on... `e.target._popup._contentNode.childNodes[0].attributes[0]`. Yeah, dirty, but it works. *phew*
    – Nighto Jul 15 '15 at 02:51
17

Javascript objects can have any properties defined on them. Set popup.marker to the referenced marker when you create the popup. Then you can access it later in the event handler.

datashaman
  • 8,301
  • 3
  • 22
  • 29
  • Excellent Idea, because in my case `e.popup._source` was `null` – Léo Mar 28 '16 at 08:27
  • This answer is arguable better than the accepted one, since the `e.popup._source` can indeed be missing, for instance if the popup was opened/closed programmatically (instead of clicking). – Roberto Mar 12 '20 at 14:50
3

Other answers didn't work, but this does:

map.on('popupopen', function(e) { alert(e.popup._source._popup._content); });

Guess this library is pretty volatile ...and I'm not sure why it's this complicated to transmit such information in the first place. <shrug>

Jan Kyu Peblik
  • 1,435
  • 14
  • 20
1

To get the marker id, you can use this code:

map.on('popupopen', function(e) {
  var marker = e.popup._source.feature.properties.markerid;
});
Waseem Senjer
  • 1,026
  • 3
  • 14
  • 25
0

I wanted to find an option which didn't use private stuff - this method sets properties on the popup which can be accessed through popupopen and popupclose events:

const map = L.map('map').setView( [ 53.749943495499345, -2.058831736626878 ], 19 );
L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '© <a target="attribution" href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo( map );
/* create marker */
const marker = L.marker( [ 53.749943495499345, -2.058831736626878 ] ).addTo( map );
/* set property on marker */
marker.markerid = 'delightful';
/* create popup */
const popup = L.popup().setContent('The New Delight');
/* set properties on popup */
popup.marker = marker;
popup.markerid = marker.markerid;
/* bind popup to marker */
marker.bindPopup(popup);
/* access markerid when popup opens */
map.on( 'popupopen', e => {
    console.log( e.popup.markerid );
});
/* access marker when popup closes */
map.on( 'popupclose', e => {
    console.log( e.popup.marker.markerid );
    e.popup.marker.setOpacity(0.2);
});
0

You can create a different listener for each popup you create :

yourMarker1.bindPopup(popupContent1).on("popupopen", function(event){
    //this will be fired only for this specific popup of marker1 .
});

yourMarker2.bindPopup(popupContent2).on("popupopen", function(event){
    //this will be fired only for this specific popup of marker2.
});
Neekobus
  • 1,870
  • 1
  • 14
  • 18