Josh Josh - 5 months ago 201
Javascript Question

Click link inside Leaflet Popup and do Javascript

I have a leaflet map up and running. It overlays a series of polygons (via GeoJSON) on the map and attaches popups to each polygon. Each of the popups display information about that polygon.

I'd like to have inside the popup a link that, when clicked, runs a javascript function that pulls further smaller polygons via AJAX and shows them.

I can't get the script to catch a click on the link via the normal jQuery/Javascript click events. Here's what I mean by normal (the following doesn't work):

$('a .smallPolygonLink').click(function(e){
console.log("One of the many Small Polygon Links was clicked");
});


The bindPopup part is as follows. It runs on each polygon when made and it pops up correctly on clicking on a polygon. It does show the link, just won't run the above code on click.

var popupContent = "Basic Information..." + '<a class="smallPolygonLink" href="#">Click here to see the smaller polygons</a>';
layer.bindPopup(popupContent);


Here's a JSFiddle illustrating the example, though in a far simpler form. http://jsfiddle.net/2XfVc/4/

Answer

The link element inside the popup is being dynamically generated from your markup each time the popup is opened. That means the link doesn't exist when you're trying to bind the handler to it.

The ideal approach here would be to use on to delegate event handling to the popup element or an ancestor of it. Unfortunately, the popup prevents event propagation, which is why delegating event handling to any static elements outside the popup won't work.

What you can do is preconstruct the link, attach the handler, and then pass it to the bindPopup method.

var link = $('<a href="#" class="speciallink">TestLink</a>').click(function() {
    alert("test");
})[0];
marker.bindPopup(link);

Here is a demonstration: http://jsfiddle.net/2XfVc/7/

In general, to insert any sort of complex markup with multiple event handlers, use the folowing approach:

// Create an element to hold all your text and markup
var container = $('<div />');

// Delegate all event handling for the container itself and its contents to the container
container.on('click', '.smallPolygonLink', function() {
    ...
});

// Insert whatever you want into the container, using whichever approach you prefer
container.html("This is a link: <a href='#' class='smallPolygonLink'>Click me</a>.");
container.append($('<span class="bold">').text(" :)"))

// Insert the container into the popup
marker.bindPopup(container[0]);

Here is a demo: http://jsfiddle.net/8Lnt4/

See this Git issue for more on event propagation in leaflet popups.

Comments