1

I am using the leaflet library. I am working on a project that has custom markers being placed on the map. Once placed, the markers have a "click" event firing that opens a popUp with two buttons inside. The buttons appear, but both return undefined in the console. Does anyone know why?

Here is my code with a lot of help from this stackoverflow question:

Adding buttons inside Leaflet popup

// Define event for clicking on Markers

function renameDeleteChoice(e) {

var choicePopUp = L.popup();
var container = L.DomUtil.create('div'),
  renametBtn = this.createButton('Rename', container),
  deleteBtn = this.createButton('Delete', container);

choicePopUp
  .setLatLng(e.latlng)
  .setContent(container)
  .openOn(myMap);

  L.DomEvent.on(renameBtn, 'click', () => {
    alert("My name is renameBtn. I have been clicked");
  });

  L.DomEvent.on(deleteBtn, 'click', () => {
    alert("My name is deleteBtn. I have been clicked.");
  });
}

function createButton(label, container) {
    var btn = L.DomUtil.create('button', '', container);
    btn.setAttribute('type', 'button');
    btn.innerHTML = label;
    return btn;
}

The above is the function for creating the buttons inside the div. The below is the code for creating the custom markers, and the event function is nested inside it:

// Creates the custom markers added by the user and stores them to 
// localStorage

var markers = [];
var customLayer = new L.layerGroup();
myMap.on('contextmenu', function(e) {
      var marker = L.marker(e.latlng,
      {icon : flagIcon}).addTo(customLayer).addTo(myMap);
      marker.bindTooltip("<b>Custom</b>", {permanent: true, offset: [-20, 
20],direction: "bottom"});
      customLayer.addTo(myMap);
      markers.push({ coords: e.latlng, name: "<b>Custom</b>" });

// Defines the choice between the two buttons on click

      marker.on('click', function(e) {
        renameDeleteChoice(e);
});

At first, I thought it was a scoping issue, so I tried several variations, but I could not get it to work. Then, I tried assigning an id to each button with the el.id method, and then I assigned each button to a variable with document.getelementById, but that did not work either. Here is the documentation for the library if anyone needs it.

https://leafletjs.com/reference-1.3.4.html

Thanks in advance for any guidance.

2 Answers2

0

After reading some documentation, i suggest try next modifications and check the developer console for messages:

FISRT

L.DomEvent.on(renameBtn, 'click', function(ev) {
    console.log('Rename button clicked!');
});

L.DomEvent.on(deleteBtn, 'click', function(ev) {
    console.log('Delete button clicked!');
});

SECOND

L.DomEvent.on(renameBtn, 'click', function(ev) {
    console.log('Rename button clicked!');
}, this);

L.DomEvent.on(deleteBtn, 'click', function(ev) {
    console.log('Delete button clicked!');
}, this);

Also, follow the suggestion of @Pal Singh:

function renameDeleteChoice(e)
{
    var choicePopUp = L.popup();
    var container = L.DomUtil.create('div'),
    renametBtn = this.createButton('Rename', container),
    deleteBtn = this.createButton('Delete', container);

    // Here try First and Second options mentioned previously.
    L.DomEvent.on(renameBtn, 'click', function(ev) {
        console.log('Rename button clicked!');
    });

    L.DomEvent.on(deleteBtn, 'click', function(ev) {
        console.log('Delete button clicked!');
    });

    choicePopUp.setLatLng(e.latlng).setContent(container).openOn(myMap);
}
Shidersz
  • 16,846
  • 2
  • 23
  • 48
0

I believe the reason the buttons return undefined is because they are just being referred to as elements. That makes them empty. In either case, I thought I would post a solution to the problem that I found:

First, we make two buttons, and we wrap them in a parent div. Give each of the elements a unique id.

<div id="choiceContainer">
<button id="renameBtn" name="button">Rename</button>
<button id="deleteBtn" name="button">Delete</button>
</div>

Define the function for what happens after the click event. Since the parent div already contains the two buttons, they will populate inside the div when you call the function. Clicking on each button will generate the respective message.

function renameDeleteChoice(e) {

var choicePopUp = L.popup();
var container = document.getElementById('choiceContainer');
var renameBtn = document.getElementById('renameBtn');
var deleteBtn = document.getElementById('deleteBtn');


choicePopUp.setLatLng(e.latlng).setContent(container).openOn(myMap);

  L.DomEvent.on(renameBtn, 'click', function(ev) {
      console.log('Rename button clicked!');
  }, this);

  L.DomEvent.on(deleteBtn, 'click', function(ev) {
      console.log('Delete button clicked!');
  }, this);
}

This is where we call the function. Keep scope in mind when calling this or any function. If it will be reused often, global scope may be a good idea.

   marker.on('click', function(e) {
   renameDeleteChoice(e);