sagens
sagens

Reputation: 1

How to get Leaflet.markercluster working with CMS in Webflow

I have found the Leaflet script with Webflow CMS integration from forresto on Webflow. LINK: https://webflow.com/website/Geo-Components-for-Webflow

I would like to include the Leaflet.markercluster javascript in the code, since I have a lot of locations and it starts to get messy.

Anyone who can help with the code?

I have tried to include the markercluster.js and L.markerClusterGroup

The first code:

<script>
window.addEventListener('DOMContentLoaded', function() {

  var places = Array.from(document.querySelectorAll('[data-geo-place]'));
  places.forEach(function(el){
    var elCoords = el
      .querySelector('[data-geo-coordinates]')
      .textContent
      .split(',')
      .map(Number);
    var value = {coordinates: {
      latitude: elCoords[0], 
      longitude: elCoords[1],
    }}
    el.value = value;
    // Just for debug(?)
    el.setAttribute('data-geo-value', JSON.stringify(value));
  });

});
</script>

The second code:

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
   integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
   crossorigin=""/>
 <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
   integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA=="
   crossorigin=""></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.4/leaflet.markercluster.js"></script>
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.4/MarkerCluster.Default.css" />

<script>
window.addEventListener('DOMContentLoaded', function() {

  Array.from(document.querySelectorAll('[data-geo-map]')).forEach(function(mapEl) {
    var mapId = mapEl.getAttribute('data-geo-map');
    var map = L.map(mapEl);

        L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
         maxZoom: 18,
         id: 'mapbox.light',
          accessToken: 'NOT SHOWN HERE',
        style: 'NOT SHOWN HERE '
        }).addTo(map);

    var myIcon = L.icon({
    iconUrl: 'myIcon.svg',

    iconSize:     [38, 38], // size of the icon
    iconAnchor:   [19, 38], // point of the icon which will correspond to marker's location
    popupAnchor:  [0, 0] // point from which the popup should open relative to the iconAnchor

});

    var allCoordinates = [];
    var markers = []
    Array.from(document.querySelectorAll('[data-geo-place="' + mapId + '"]')).forEach(function(placeEl) {
      var coordinates = [placeEl.value.coordinates.latitude, placeEl.value.coordinates.longitude]
      allCoordinates.push(coordinates);
      var marker = L.markerClusterGroup(coordinates).addTo(map);
      var marker = L.marker(coordinates, {icon: myIcon}).addTo(map)
            .bindPopup(placeEl.innerHTML);
      markers.push(marker);
      // Click place element to pan map
      placeEl.addEventListener('click', function(event) {
        map.panTo(coordinates, {animate: true, duration: 0.5});
        // Close other popups
        markers.forEach(function(otherMarker) {
          otherMarker.closePopup();
        });
        marker.openPopup();
      });
    });

    // Zoom to the markers added
    map.fitBounds(L.latLngBounds(allCoordinates));
  });

});
</script>

Upvotes: 0

Views: 490

Answers (1)

ghybs
ghybs

Reputation: 53300

Welcome to SO!

Looks like you simply confused a MarkerClusterGroup with a Marker.

In Leaflet, you have Layer Groups, which contain child Layers like Markers. Your MarkerClusterGroup is such a Layer Group.

Simply instantiate the Group outside of your places forEach loop (but inside your maps loop, since you need at least one Group per map).

Then add your Markers into it, instead of directly to the map.

mapEls.forEach(mapEl => {
  const map = L.map(mapEl)

  const mcg = L.markerClusterGroup().addTo(map)

  placeEls.forEach(placeEl => {
    const coordinates = [placeEl.value.coordinates.latitude, placeEl.value.coordinates.longitude]
    const marker = L.marker(coordinates).addTo(mcg)
  })
})

Note: as for your click listener to open the Marker Popup, you will have issues when the Marker is hidden under a Cluster. Use mcg.zoomToShowLayer(marker, cb) and open tje popup in the cb callback. You should have other posts on this. Feel free to open a new question if you need help.

Upvotes: 0

Related Questions