Search code examples
javascriptjquerygeolocationleafletmapbox

Change other HTML elements after clicking on map marker in Mapbox?


This Mapbox tutorial shows how to build a list and have the map pan over to the map marker once the list item had been clicked.

JSFiddle

This is how the a list item handles its click event based on a specific marker:

// Iterate through each feature layer item, build a
// marker menu item and enable a click event that pans to + opens
// a marker that's associated to the marker item.
myLayer.eachLayer(function(marker) {
  var link = info.appendChild(document.createElement('a'));
  link.className = 'item';
  link.href = '#';

  // Populate content from each markers object.
  link.innerHTML = marker.feature.properties.title +
    '<br /><small>' + marker.feature.properties.description + '</small>';
  link.onclick = function() {
    if (/active/.test(this.className)) {
      this.className = this.className.replace(/active/, '').replace(/\s\s*$/, '');
    } else {
      var siblings = info.getElementsByTagName('a');
      for (var i = 0; i < siblings.length; i++) {
        siblings[i].className = siblings[i].className
          .replace(/active/, '').replace(/\s\s*$/, '');
      };
      this.className += ' active';

      // When a menu item is clicked, animate the map to center
      // its associated marker and open its popup.
      map.panTo(marker.getLatLng());
      marker.openPopup();
    }
    return false;
  };
});

How can the reverse be done? Right now if you click directly on a marker, the popup appears but the list items aren't updated to the chosen marker. I'm not quite sure how to bind a click event to the map markers that corresponds to a specific list item.


Solution

  • You would simply need to create a listener attached to the "click" event of your marker, and to keep a reference of your link within the marker.

    Then the listener would do the same instructions as the first part of your link.onclick > else block, when it resets the links classes and sets the "active" class on the link of the clicked marker.

    Within the anonymous function of myLayer.eachLayer, you could add after the link variable has been assigned:

    // Marker click interaction.
    marker.on("click", markerClickSetLinkActive);
    
    // Keep a reference to the link within the marker.
    marker.link = link;
    

    And somewhere in your script file:

    // Marker click interaction function to handle the click event.
    function markerClickSetLinkActive(event) {
      var marker = event.target;
      var link = marker.link;
    
      var siblings = info.getElementsByTagName('a');
      for (var i = 0; i < siblings.length; i++) {
        siblings[i].className = siblings[i].className
          .replace(/active/, '').replace(/\s\s*$/, '');
      };
      link.className += ' active';
    }
    

    Demo: http://plnkr.co/edit/oueHiszYQNXEX1oBkXkD?p=preview (using polygons instead of markers, but the process is almost identical).