2

I am creating a map in leaflet which has markers on the map of various businesses. I created the markers by looping through a list of objects without a problem.

However, I want to be able to pan to each of these markers using a sidebar on my website (outside of the leaflet map). I can do this by creating each individual marker as a variable, but my list is huge and too big to do this manually.

My list of businesses are objects like below:

   businesses = [{
       'name': 'Business name 1',
       'location': 'address',
       'id': 'businessid',
       'website': 'http://website',
       'coords':[0,0]
   },]

I created the markers by doing this:

businesses.forEach(element => 
    L.marker([element.coords[0],element.coords[1]]).addTo(mymap)
   .bindPopup("<strong>"+element.name+"</strong>"));

But I think I can only link to the above markers in my html sidebar if they are declared as a variable. How can I recreate the code above ^ but set each loop instance as a variable? Is this possible?

3 Answers 3

2

You just need to create an array to store each marker's reference. Let's call this array markers. Then, your code would be like:

let markers = [];

businesses.forEach((element, i) => 
   markers[i] = L.marker([element.coords[0],element.coords[1]]).addTo(mymap)
   .bindPopup("<strong>"+element.name+"</strong>"));

Then, you can pan to any marker by its index (i):

panToMarker(i) {
    map.panTo(markers[i].getLatLng());
}
1

I think adding the mapped elements to an array would be a good idea, and you can have a look at this link How do I create dynamic variable names inside a loop? , I think it will explain more when you check the threads and read multiple opinions

1

You need to create a reference between a marker and the html element in your side. You can use the _leaflet_id for this, because it is a unique id on your map.

  1. I created a function where I can pass the layer and I read out the _leaflet_id of the marker and store it on the html element as the custom attribute data-marker.
  2. Then I added a click listener.
  3. In the click listener, I read out the marker id over the attribute of the clicked html element.
  4. Find marker on the map and pan to it.
function createSidebarElement(layer){
    //Step 1
    var elm = "<div class='sidebar-elm' data-marker='"+layer._leaflet_id+"'>Marker: "+layer.getLatLng().toString()+"</div>";
  
  // create a temp div to create element from string
  var temp = document.createElement('div');
  temp.innerHTML = elm.trim();
  var htmlElm = temp.firstChild
  
  //Step 2
  L.DomEvent.on(htmlElm,'click',zoomToMarker);
  sidebar.append(htmlElm);
}

function zoomToMarker(e){
  //Step 3
  var clickedElm = e.target;
  var markerId = clickedElm.getAttribute('data-marker');
  
  //Step 4
  var marker = fg.getLayer(markerId);
  map.panTo(marker.getLatLng());
}

Default Demo: https://jsfiddle.net/falkedesign/cgebnskx/

Demo for your usecase: https://jsfiddle.net/falkedesign/3fqtjy7c/

Not the answer you're looking for? Browse other questions tagged or ask your own question.