1

Here is a javascript beginners problem. I created a custom popup at fixed position(leaflet). After clicking a marker that opens the popup I can't close it by clicking the close button. I can click a different marker though , but the popup wrapper remains open showing the content attached to each different marker. So the content of the popup changes by clicking the markers but can't close the popup by clicking the close button.
I tried an eventListener. I need that piece of code that does the job. Any help would be appreciated.

// Adds custom marker

var redFlag = L.icon({
    iconUrl: 'images/mapmarker2.png',
    iconSize: [34, 34],
    iconAnchor: [17,34]
});

// Adds markers and popup
// geoJSON file stored in 'art' variable

const myLayer = L.geoJSON(art, {
    pointToLayer: function (feature, latlng) {
          return L.marker(latlng, {icon: redFlag});

},
onEachFeature: function ( feature, layer) {
    layer.on('click', function(e){

// popup content

   var getWrap = document.getElementById('wrapper');
        var wrap = getWrap.appendChild(document.createElement('div'));
        wrap.className = 'wrapper';
        wrap.innerHTML =  
           `<div class="close">X</div>`+ 
           `<div class="popUpContent" style="background-color:#e8f4ff">`+
           `<div class='pic'><img src = 
            "images/${feature.properties.image}"></div>`+ 
           `<div class="puName"><span 
            class="puName">${feature.properties.name}</span><br>`+
           `<span class="puTitle">"${feature.properties.title}"</span><br>`+ 
           `<div class="extra3">${feature.properties.extra}</div></div>`+ 
           `</div>`;

    if(!feature.properties.title){

        wrap.innerHTML =  
            `<div class="close">X</div>`+
            `<div class="popUpContent" style="background-color:#e8f4ff">` + 
             `<div class='pic'><img src = 
             "images/${feature.properties.image}"></div>`+ 
             `<div class="puName"><span 
             class="puName">${feature.properties.name}</span><br>`+ 
             `<div class="extra3">${feature.properties.extra}</div></div>`+ 
             `</div>`;
         }

// Add eventlistener to the close button

document.querySelector('.close').addEventListener( 'click', closePopup);
      function closePopup(e){

        if(event.target.matches('.close')){
            document.querySelector(".wrapper").style.display='none'
        }else if(document.querySelector(".wrapper").style.display='block'){
            document.querySelector(".wrapper").style.display='none';
           }
         }

       });
    }

});

mymap.addLayer(myLayer)
Noud
  • 55
  • 9
  • You don't need 3x `=` for `document.getElementById("wrapper").style.display === 'block'` and your `else` condition is executing the same style for `wrapper` so the results of that `if` condition are meaningless. You are also duplicating the `wrapper` id which I do not recommend. – NewToJS May 24 '19 at 07:09
  • Thanks NewToJS, I changed that bit of code , but still experiencing the same problem. – Noud May 24 '19 at 07:29
  • You are still creating duplicate **ID**'s of `wrapper`. IDs are supposed to be unique. In `document.getElementById("wrapper").innerHTML` you are also adding a `div` with the same `id` => `
    `
    – NewToJS May 24 '19 at 07:36

3 Answers3

1

You are adding event listener for close before pop-up is created. You should add this listener at the end of your layer.on('click', function(e){... in the onEachFeature function.

To be sure that listener added only ones, use removeEventListener before adding an event.

Thevs
  • 3,189
  • 2
  • 20
  • 32
0

The event listener does not work because the popup is dynamically created. See Attach event to dynamic elements in javascript

Alternatively, what I always do, is just include the popup in the HTML. But set the CSS display property to display: none. When you need to show the popup set the display to block for example.

This way you can also add the event listener when the page loads, because the popup is not dynamically created. Just hidden until you need it.

Kelvin
  • 320
  • 4
  • 19
  • Still doesn't work the way I want it. I'm able to open a popup, close it, open another one and then it got stuck. The wrapper remains open and shows the content attached to the individual markers . Guess I'll have to do it according to leaflet's built-in openpopup/closepopup – Noud May 24 '19 at 14:14
0

I found the answer. It is how you construct your dynamically generated DOM element, wich in this case is the popup. Create one empty div with id="popup" in the div with id="mapid" in your HTML file. The rest is generated dynamically. The if statement of the eventlistener only needs that block of code necessary when a condition is true.

const element = document.getElementById('popup');

      element.innerHTML =
            `<div class= "wrapper" style="background-color:#fff">`+
            `<div class="close">X</div>`+ 
            `<div class="popUpContent" style="background-color:#e8f4ff">` +
            `<div class='pic'><img src = "images/${feature.properties.image}"></div> 
             <p>`+ 
            `<div class="puName"><span class="puName">${feature.properties.name} 
              </span><br>`+
            `<span class="puTitle">"${feature.properties.title}"</span><br><p>` + 
            `<div class="extra3">${feature.properties.extra}</div></div>`+ 
            `</div></div>`;

  // the eventListener

            document.getElementById('popup').addEventListener( 'click', closePopup);
                    function closePopup(e){
                if(document.querySelector('.wrapper').style.display = 'block'){
                   document.querySelector('.wrapper').style.display='none';
                }
             }                 
kboul
  • 13,836
  • 5
  • 42
  • 53
Noud
  • 55
  • 9