Mapbox GL JS – Setting Default State of Toggle Layers

layersmapbox-gl-js

How do I change the default state (off or on) of a toggle menu in Mapbox GL JS? The code that I'm using came from another question on this site Mapbox GLJS – group layers

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title></title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.20.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.20.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>
<body>

<style>
    #menu {
        background: #fff;
        position: absolute;
        z-index: 1;
        top: 10px;
        right: 10px;
        border-radius: 3px;
        width: 120px;
        border: 1px solid rgba(0,0,0,0.4);
        font-family: 'Open Sans', sans-serif;
    }

    #menu a {
        font-size: 13px;
        color: #404040;
        display: block;
        margin: 0;
        padding: 0;
        padding: 10px;
        text-decoration: none;
        border-bottom: 1px solid rgba(0,0,0,0.25);
        text-align: center;
    }

    #menu a:last-child {
        border: none;
    }

    #menu a:hover {
        background-color: #f8f8f8;
        color: #404040;
    }

    #menu a.active {
        background-color: #3887be;
        color: #ffffff;
    }

    #menu a.active:hover {
        background: #3074a4;
    }
</style>

<nav id="menu"></nav>
<div id="map"></div>

<script>
   mapboxgl.accessToken = 'pk.eyJ1IjoiY2RyaWNlIiwiYSI6ImNpcDZvMTU2cDAwMGR2MW03aXZ1Y2xpdXAifQ.DIB1RcA8uDyXSVvyz7Skcg';

// Set bounds 
var bounds = [
    [5.336040, 47.678506], // Southwest coordinates
    [7.202343, 48.697659]  // Northeast coordinates
];

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/cdrice/cip6vwuus000wdkm3q2adkr24',
    center: [6.95, 48.28],
    zoom: 8.5,
    maxBounds: bounds // Sets bounds as max
});

toggleLayer(['reciprocite-gpv', 'reciprocite-gap','reciprocite-gprmv'], '1');
toggleLayer(['reciprocite-non-recipro','reciprocite-eh3vv'], '2');

function toggleLayer(ids, name) {
    var link = document.createElement('a');
    link.href = '#';
    link.className = 'active';
    link.textContent = name;

    link.onclick = function (e) {
        e.preventDefault();
        e.stopPropagation();
        for (layers in ids){
            // console.log(ids[layers]);
        var visibility = map.getLayoutProperty(ids[layers], 'visibility');

        if (visibility === 'visible') {
            map.setLayoutProperty(ids[layers], 'visibility', 'none');
            this.className = '';
        } else {
            this.className = 'active';
            map.setLayoutProperty(ids[layers], 'visibility', 'visible');
        }
        }

    };

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

</script>

</body>
</html>

Best Answer

Since the layers in the map are all off by default, you can change this:

link.className = 'active';

to:

link.className = '';

If you want the state of your toggle to reflect what's in the map, it's a bit more code and you need to wait for the map to load before building the toggles. Here's a modified example that does this:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title></title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.20.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.20.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>
<body>

<style>
    #menu {
        background: #fff;
        position: absolute;
        z-index: 1;
        top: 10px;
        right: 10px;
        border-radius: 3px;
        width: 120px;
        border: 1px solid rgba(0,0,0,0.4);
        font-family: 'Open Sans', sans-serif;
    }

    #menu a {
        font-size: 13px;
        color: #404040;
        display: block;
        margin: 0;
        padding: 0;
        padding: 10px;
        text-decoration: none;
        border-bottom: 1px solid rgba(0,0,0,0.25);
        text-align: center;
    }

    #menu a:last-child {
        border: none;
    }

    #menu a:hover {
        background-color: #f8f8f8;
        color: #404040;
    }

    #menu a.active {
        background-color: #3887be;
        color: #ffffff;
    }

    #menu a.active:hover {
        background: #3074a4;
    }
</style>

<nav id="menu"></nav>
<div id="map"></div>

<script>
   mapboxgl.accessToken = 'pk.eyJ1IjoiY2RyaWNlIiwiYSI6ImNpcDZvMTU2cDAwMGR2MW03aXZ1Y2xpdXAifQ.DIB1RcA8uDyXSVvyz7Skcg';

// Set bounds
var bounds = [
    [5.336040, 47.678506], // Southwest coordinates
    [7.202343, 48.697659]  // Northeast coordinates
];

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/cdrice/cip6vwuus000wdkm3q2adkr24',
    center: [6.95, 48.28],
    zoom: 8.5,
    maxBounds: bounds // Sets bounds as max
});

map.on('load', function() {
  toggleLayer(['reciprocite-gpv', 'reciprocite-gap','reciprocite-gprmv'], '1');
  toggleLayer(['reciprocite-non-recipro','reciprocite-eh3vv'], '2');

  function toggleLayer(ids, name) {
      var link = document.createElement('a');
      link.href = '#';
      // Get the visibility for all layers in the ids argument.
      var visibility = ids.map(function(id) {
        return map.getLayoutProperty(id, 'visibility');
      });
      // Get the unique values.
      var visUnique = visibility.filter(uniques);
      // Default to not visible.
      var visCssClass = '';
      // If all layers are visible, use the 'active' class so the toggle is "on".
      if ( visUnique.length === 1 && visUnique[0] === 'visible' ) {
        visCssClass = 'active';
      }
      link.className = visCssClass;
      link.textContent = name;

      link.onclick = function (e) {
          e.preventDefault();
          e.stopPropagation();
          for (layers in ids){
          var visibility = map.getLayoutProperty(ids[layers], 'visibility');

          if (visibility === 'visible') {
              map.setLayoutProperty(ids[layers], 'visibility', 'none');
              this.className = '';
          } else {
              this.className = 'active';
              map.setLayoutProperty(ids[layers], 'visibility', 'visible');
          }
          }

      };

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

  // http://stackoverflow.com/a/14438954/1934
  function uniques(value, index, self) {
    return self.indexOf(value) === index;
  }

})

</script>

</body>
</html>
Related Question