7

I am using Leaflet in order to render a map. I created a map with markers and I don't know how to implement the Event Listener 'onClick' on each Marker.

My code

var stops = JSON.parse(json);
var map = new L.Map('map', {
  zoom: 12,
  minZoom: 12,
  center: L.latLng(41.11714, 16.87187)
});
map.addLayer(L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
  attribution: 'Map data',
  maxZoom: 18,
  id: 'mapbox.streets',
  accessToken: '-----'
}));
var markersLayer = new L.LayerGroup();
map.addLayer(markersLayer);


//populate map from stops
for (var i in stops) {
  L.marker(L.latLng(stops[i].Position.Lat, stops[i].Position.Lon), {
    title: stops[i].Description
  }).addTo(markersLayer).bindPopup("<b>" + stops[i].Description + "</b>").openPopup();
}

Example

map.on('click', function(e) {
    alert(e.latlng);
});

Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function:

function onClick(e) { ... }

map.on('click', onClick);
map.off('click', onClick);
11

Welcome to GIS Stack Exchange!

There should be no special difficulty in attaching a callback to marker(s) click event. You would simply use myMarker.on('click', callback) like you did with the map. You would also have to do that for every marker you want to attach a callback to.

Another possibility would be to add all your markers into a Feature Group (e.g. simply instantiate your markersLayer with L.featureGroup() instead of L.layerGroup()), so that you can attach the callback directly to that Group. It will receive the click events from individual markers, and you can access the individual clicked feature using event.layer.

var markersLayer = L.featureGroup().addTo(map);

// populate map from stops…

markersLayer.on("click", function (event) {
    var clickedMarker = event.layer;
    // do some stuff…
});

Demo: http://jsfiddle.net/ve2huzxw/74/

Similar question asked by someone else on Leaflet forum: https://groups.google.com/forum/#!topic/leaflet-js/RDTCHuLvMdw

  • Just to add, event.layer.properties will give you access to the array of all the properties (metadata) of your markers, as per GeoJSON format. So you can assign event.layer.properties.description = stops[i].Description for example. – Nikhil VJ Feb 25 '18 at 17:04
3

Modify your map population loop to assign properties to your marker.

//populate map from stops
for (var i in stops) {
  var oneMarker = L.marker(L.latLng(stops[i].Position.Lat, stops[i].Position.Lon), {
    title: stops[i].Description
  }).bindPopup("<b>" + stops[i].Description + "</b>").openPopup();

  oneMarker.properies.name = stops[i].Name;
  oneMarker.properies.description = stops[i].Description;
  oneMarker.properies.othervars = stops[i].othervars;
  oneMarker.addTo(markersLayer);
}

Later, to access these properties (feature properties as they're called) in the onclick event,

markersLayer.on("click", markerOnClick);

function markerOnClick(e) {
  var attributes = e.layer.properties;
  console.log(attributes.name, attributes.desctiption, attributes.othervars);
  // do some stuff…
}

The properties.var approach has the added benefit of making your marker be in the standard GeoJson format. Makes it compatible if, say, you need to export the data as shapefile, import markers from shapefile, etc.

  • I am trying to incorporated your suggestion into my own setup. But adding a simple oneMarker.properties gives me an error message "oneMarker.properties is undefined". I am overlooking something obvious?? regards btw: you misspelled properies ........properties in your example code – alex May 17 at 9:12
  • ah i think i found a solution: I had to add oneMarker.properties = {}; btw: is it correct to use var oneMarker or should this be a dynamic name? – alex May 17 at 9:26
  • @alex good to know about the properties hack. Yes, it's fine to use var oneMarker - it's local scope within the for loop, and the layer.addTo() line adds it value. (like: a=3; array1.push[a]; will add value 3 to the array, not a reference to a itself.) – Nikhil VJ May 17 at 15:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.