Leaflet – How to Show/Hide Layer by Clicking on HTML Link

layersleaflet

I have 7 GPX files that I successfully loaded into a Leaflet map.
My problem is that I would like to show/hide each of them using some link on the web page.
Let say that links have the following code:

<a href="#" id="GPX1">Link show/hide GPX1</a>
<a href="#" id="GPX2">Link show/hide GPX2</a>
<a href="#" id="GPX3">Link show/hide GPX3</a>
<a href="#" id="GPX4">Link show/hide GPX4</a>
<a href="#" id="GPX5">Link show/hide GPX5</a>
<a href="#" id="GPX6">Link show/hide GPX6</a>
<a href="#" id="GPX7">Link show/hide GPX7</a>

and the JS script I am using is the following

var mbAttr = 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
            'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'


// replace this with your own mapbox token!
var token = 'my_token_here';
var mapboxUrl = 'https://api.mapbox.com/styles/v1/mapbox/streets-v10/tiles/{z}/{x}/{y}@2x?access_token=' + token;

var OpenStreetMap_Mapnick=L.tileLayer(mapboxUrl, {id: 'mapbox/light-v9', attribution: mbAttr})

var map = L.map('mapid', {
        center: [45.43538, 12.33297],
        zoom: 14,
    layers: [OpenStreetMap_Mapnick]
});

var control = L.control.layers(null, null).addTo(map);

for (let i = 1; i <= 7; i++) {
  new L.GPX('gpx/MuVe_7D/MuVe_7D_T'+i+'.gpx', {
    async: true,
    marker_options: {
      startIconUrl: 'assets/pins/Pin_ATG.png',
      endIconUrl: 'assets/pins/Pin_CUR.png',
      shadowUrl: 'assets/pins/Pin_shadow.png'
    }
  }).on('loaded', function(e) {
    var gpx = e.target;
    control.addOverlay(gpx, 'gpr_GPX'+i);
  }).addTo(map);
}


$("#GPX1").click(function(event) {
    event.preventDefault();
    if(map.hasLayer(gpr_GPX1)) {
        $(this).removeClass('selected');
        map.removeLayer(gpr_GPX1);
    } else {
        map.addLayer(gpr_GPX1);
        $(this).addClass('selected');
   }
});

now, when I click on the GPX1 link I get the following error

Uncaught ReferenceError: gpr_GPX1 is not defined

How can I solve it?

I am using this snippet of code to show/hide layers but it doesn't work. The curious fact about it is that if I plot a POI the show/hide functionality from the link works, it seems I am doing something wrong defining the layers.

Best Answer

Leaflet method map.hasLayer requires layer as argument, you are giving it nonexistent gpr_GPX1 variable/object.

When creating GPX layers, they can be stored in an array and later referenced by index coming from link HTML element id.

Assuming all your GPX layers being treated equal, code could then look something like this, covering all 7 GPX layers:

var gpxLayers = [];

for (let i = 1; i <= 7; i++) {
  gpxLayers[i] = new L.GPX('gpx/MuVe_7D/MuVe_7D_T'+i+'.gpx', {
    async: true,
    marker_options: {
      startIconUrl: 'assets/pins/Pin_ATG.png',
      endIconUrl: 'assets/pins/Pin_CUR.png',
      shadowUrl: 'assets/pins/Pin_shadow.png'
    }
  }).on('loaded', function(e) {
    var gpx = e.target;
    control.addOverlay(gpx, 'gpr_GPX'+i);
  }).addTo(map);
}

$("*[id^='GPX']").click(function(evt) {
  evt.preventDefault();
  var i = parseInt(evt.target.id.substr(-1));
  var gpxLayer = gpxLayers[i];
  if(map.hasLayer(gpxLayer)) {
    $(this).removeClass('selected');
    map.removeLayer(gpxLayer);
  } else {
    map.addLayer(gpxLayer);
    $(this).addClass('selected');
 }
});