2
votes

I am new to Mapbox and javascript. I'm attempting to slightly modify a Mapbox GL code example, found here, which allows for the toggling on/off of multiple layers.

I have four layers, and I would like the user to toggle these layers on and off, but when the map initially displays, I only want one layer toggled on. I am able to have three of the layers turned off when the page loads (here is one as an example):

 map.addSource("gnat-4zdrvs", {
     type: 'vector',
       url: 'mapbox://jesselangdon.bbtex1ps'
 });
 map.addLayer({
     "id": "gnat",
     "type": "line",
     "source": "gnat-4zdrvs",
     "source-layer": "gnat-4zdrvs",
     "minzoom": 8,
         "filter": [
             "==",
             "$type",
             "LineString"
        ],
        "layout": {
            "visibility": "none",
            "line-cap": "round",
            "line-join": "round"
        },
        "paint": {
            "line-width": 2,
            "line-color": {
                "base": 1,
                "type": "interval",
                "property": "C_Sin",
                "stops": [
                    [1,"hsl(189, 81%, 79%)"],
                    [1.02,"hsl(189, 91%, 65%)"],
                    [1.04, "hsl(189, 81%, 53%)"],
                    [1.06,"hsl(189, 83%, 43%)"],
                    [1.08,"hsl(189, 89%, 34%)"],
                    [1.1,"hsl(189, 90%, 28%)"],
                    [1.3,"hsl(189, 96%, 21%)"]
                ],
                "default": "hsl(0, 0%, 50%)"
            }
        }
   })

However, my limited knowledge of Javascript is keeping from figuring out how to set up the menu of clickable links so that only the "visible" layer is in a toggled "On" state.

Here's the code snippet which controls the toggle menu:

var toggleableLayerIds = [ 'conductivity', 'confinement', 'gnat', 'solar' ];

for (var i = 0; i < toggleableLayerIds.length; i++) {
    var id = toggleableLayerIds[i];

    var link = document.createElement('a');
    link.href = '#';
    link.className = 'active';
    link.textContent = id;

    link.onclick = function (e) {
        var clickedLayer = this.textContent;
        e.preventDefault();
        e.stopPropagation();

        var visibility = map.getLayoutProperty(clickedLayer, 'visibility');

        if (visibility === 'visible') {
            map.setLayoutProperty(clickedLayer, 'visibility', 'none');
            this.className = '';
        } else {
            this.className = 'active';
            map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
        }
    };

    var layers = document.getElementById('menu');
    layers.appendChild(link);
}

The map is viewable here. Notice that all four layers in the toggle menu are blue (meaning they are in an "On" position, when in fact the only layer that is "on" is solar). Any help, advice, or criticism is welcome... thanks!

1

1 Answers

1
votes

You are setting the class to active unconditionally on creation which will always make the link blue even if the layer is not visible. Try something like this.

    if(map.getLayoutProperty(id, 'visibility') === 'visible')
    {
     link.className = 'active';
    }

Though this will need to be done inside the onload function otherwise the property will be undefined.