2

I'm trying to get this function on my custom Leaflet map https://rodadagua.netlify.app/

I've found some very close examples and questions on here but being a complete novice unfortunately I have no idea what I´m doing.

This is essentially the same question https://stackoverflow.com/questions/17997247/change-and-change-back-leaflet-icon-on-click but with such basic knowledge I can't work it out. Also I found this question https://stackoverflow.com/questions/61890461/leaflet-map-on-click-changing-color-of-all-markers and example https://jsfiddle.net/vz7jmnqs/2/ is essentially what I'm after but again I can't work out how to include it in my code and make it work.

I want to change marker icon when clicked (so that it shows a different coloured version) and then return back to original state (original icon/colour) when click elsewhere, anywhere, eg. close the associated popup or click on the map or click on another marker.

The closet I've got to is I can change the icon on a click, but I want to change it back.

var defaultIcon = L.icon({
    iconUrl: 'scripts/leaflet/images/marker-icon.png',
    shadowUrl: 'scripts/leaflet/images/marker-shadow.png',
});

var brownIcon = L.icon({
    iconUrl: 'scripts/leaflet/images/marker-icon-brown.png',
    shadowUrl: 'scripts/leaflet/images/marker-shadow.png',
});

var testmarker = L.marker([0.0, 0.0], {icon: defaultIcon}).addTo(map);

testmarker.on('click', function(e) {
  testmarker.setIcon(brownIcon);
});   

I'm using the basic Leaflet script to define the map etc. then all of my markers and popups are set up like this example:

var marker_Waldemar = L.marker([15.0, -40.0]).addTo(map);
marker_Waldemar.bindPopup('<h3>EMEF Prof. Waldemar Rodrigues</h3><p><iframe src="https://galeriafeira.netlify.app/" width="500" height="354" style="border:none;"></iframe></p><p><b>Feira de Ci&ecirc;ncias</b></p>', {
    maxWidth : 520,
    maxHeight : 450,
});

I would like to know exactly what code I need to put in and where.

6
  • 1
    What is not clear about the answer to the first question you are mentioning?
    – TomazicM
    Jun 8, 2022 at 14:44
  • I can see that first question is essentially what I'm after as well, unforunately I have no real knowledge of what I'm doing. I've managed to put the map together with very basic understanding of code but I don't really understand the ins and outs of it. So although that answer might be what I need when I try and put that same code into my code I can't get it to work. I might be putting it in the wrong place, or need some extra functions or variables... I was hoping my with my specific code here someone might be able to very simply show me what code I need and where it needs to go.
    – andycb
    Jun 8, 2022 at 17:39
  • But in your code above there is no attempt to do what is suggested in the answer to the mentioned question. If somebody answered your question in similar way, would you just copy it, without understanding what the code does? This way you'll be in trouble all the time.
    – TomazicM
    Jun 8, 2022 at 18:06
  • My point of view was, that along with that answer and many others that I've looked at I've tried to understand them, experimented with putting them in my code, tried to learn and teach myself about it. But really I think I need to understand some basics and principals of javascript/code that I don't to be able to have an objective idea about what's going on. I didn't include that code in my code above because as long with that and many others I couldn't really understand it on a technical level, although I kind of understand the idea behind it I don't have the technical ability to use it.
    – andycb
    Jun 8, 2022 at 19:18
  • But I am trying to learn and my hope was that by providing my code (as opposed to trying to understand someone elses) that someone would be able to explain it to me. And by using my code that I understand it would make more sense. With the example below that ZRab has helped with. I understand the idea but my basic lack of knowledge means I don't really understand where it needs to fit to work and what to do to make it work. But I'm here, asking questions, trying to learn.
    – andycb
    Jun 8, 2022 at 19:22

2 Answers 2

1

Solution below is based on assumption that each marker will have a popup that opens upon marker click.

Logic goes as follows:

  • when marker is clicked, popup opens and marker icon is changed;
  • when marker popup is closed (it can be by the same marker click, popup close button click, another marker click, anywhere on map click), marker icon is set back to original icon.

Most economic way to do this is to define marker creation function, where all necessary things are taken care of:

  • marker created, on desired coordinates and with desired icon and popup;
  • processing function are defined for popupupen and popupclose marker events, where change of marker icon is taken care of.

Code for such a marker creating function could then look something like this:

function defineMarker(coords, icon, selectedIcon, popupTxt, popupWidth, popupHeight) {
  var markerIcon = icon;
  var marker = L.marker(coords, {
    icon: icon
  }).bindPopup(popupTxt, {
    maxWidth: popupWidth,
    maxHeight: popupHeight
  });
  marker.on('popupopen', function(evt) {
    marker.setIcon(selectedIcon);
  });
  marker.on('popupclose', function(evt) {
    var marker = evt.target;
    marker.setIcon(markerIcon);
  });
  
  return(marker);
}

Creation of your marker_Waldemar marker could then look like this:

var txt_Waldemar = '<h3>EMEF Prof. Waldemar Rodrigues</h3><p><iframe src="https://galeriafeira.netlify.app/" width="500" height="354" style="border:none;"></iframe></p><p><b>Feira de Ci&ecirc;ncias</b></p>'
var marker_Waldemar = defineMarker([15.0, -40.0], defaultIcon, brownIcon, txt_Waldemar, 520, 450);
marker_Waldemar.addTo(map);
9
  • Thank you very much @TomazicM I appreciate you taking the time to help. I understand your explanation, again I can understand the logic but I don't have any experience in programming aside from following tutorials online. I come from a graphic design background so I think my understanding of code in more in terms of html and defining how things look, not how they work so this is all new to me. I can see that all the different elements are defined within the function then each new marker references that original function to define the marker and therefore the functionality of the icon.
    – andycb
    Jun 10, 2022 at 21:02
  • Again I really appreciate your help and explanation. What I am trying to work out now is how to define the maxWidth and maxHeight of the popup within this new format. In my code before, I followed the Leaflet documentation and included these at the end of the bindPopup method
    – andycb
    Jun 10, 2022 at 21:04
  • ´marker_Waldemar.bindPopup('<h3>EMEF Prof. Waldemar Rodrigues</h3><p><iframe src="galeriafeira.netlify.app" width="500" height="354" style="border:none;"></iframe></p><p><b>Feira de Ci&ecirc;ncias</b></p>', { maxWidth : 520, maxHeight : 450, });`
    – andycb
    Jun 10, 2022 at 21:05
  • Wait I've figured out that I can include the options within the function, as such...
    – andycb
    Jun 10, 2022 at 21:13
  • function defineMarker(coords, icon, selectedIcon, popupTxt) { var markerIcon = icon; var marker = L.marker(coords, { icon: icon }).bindPopup(popupTxt, { maxWidth : 520, maxHeight : 400, }); marker.on('popupopen', function(evt) { marker.setIcon(selectedIcon); }); marker.on('popupclose', function(evt) { var marker = evt.target; marker.setIcon(markerIcon); }); return(marker); }
    – andycb
    Jun 10, 2022 at 21:14
1

You could have a script that changes all markers back to default and call that before you change your clicked marker.

map.eachLayer(function(layer) {
   if( layer instanceof L.Marker ) {
     layer.setIcon(defaultIcon);
    }
});
1
  • Thank you very much for your reply @ZRab where in the code would I put this? Would it have to go after every marker? Unfortunately my knowledge is next to zero so I can understand the theory of it but I have no knowledge in how to implement it.
    – andycb
    Jun 8, 2022 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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