Search code examples
reactjsleafletreact-leaflet-v3

Pass function to divIcon in React-Leaflet


I'm new to React-Leaflet (using v3), so if I'm missing something obvious that's why. For my current app I need to be able to have rotated markers on the map, which open up popups that should also be rotated by the same angle. For the general marker rotation I used the leaflet-marker-rotation plugin. This does not apply on the inside placed popup component tho.

My current approach was then to use a rotated marker for the popup that I customise via the leaflet divIcon. Problem now is, that I need buttons inside that popup which call specific functions. Since the content of the divIcon is defined via html and not JSX I haven't managed yet to pass a function.

function CustomPopup({ togglePopup, coords, data}) {
  const description = JSON.parse(data.properties.description);

  const pressButton = () => {
    console.log("pressed close");
        togglePopup()
  };

  const content = divIcon({
    className: "custom-popup",
    html: `
        <button onclick="${pressButton}">Close</button>
        <h3>${data.properties.name}</h3>
    `,
  });

  return (
      <Marker
        position={coords}
        icon={content}
        rotationAngle={180}
        rotationOrigin="top left"
      />
  );
}

On button click I get: Uncaught SyntaxError: Unexpected end of input

Is it even possible to pass a function to a divIcon? If not, does anyone has another idea on how I could create a custom rotatable popup with buttons inside?


Solution

  • I haven't tested if it is possible to apply a function in a html string but I don't think that this will work.

    You can create the html elements and append the click listener directly:

    const pressButton = () => {
        console.log("pressed close");
            togglePopup()
      };
    
    var div = document.createElement('div');
    
    var button = document.createElement('button');
    L.DomEvent.on(button, 'click', pressButton);
    div.appendChild(button);
    
    var h3 = document.createElement('h3');
    h3.innerHTML = data.properties.name;
    div.appendChild(h3);
    
    
      const content = divIcon({
        className: "custom-popup",
        html: div,
      });