Mutually exclusive layers in Leaflet layer control

A setTimeout is necessary to keep the overlayadd event from firing multiple times

by J. Albert Bowden

HTML

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css">
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<div id="map" style="height: 300px"></div>

JavaScript

var cities1 = new L.LayerGroup();
var cities2 = new L.LayerGroup();
var cities3 = new L.LayerGroup();

L.marker([39.61, -105.02]).bindPopup('This is Littleton, CO.').addTo(cities1);
L.marker([39.74, -104.99]).bindPopup('This is Denver, CO.').addTo(cities1);
L.marker([39.73, -104.8]).bindPopup('This is Aurora, CO.').addTo(cities2);
L.marker([39.77, -105.23]).bindPopup('This is Golden, CO.').addTo(cities2);
L.marker([39.64, -105.34]).bindPopup('This is Evergreen, CO.').addTo(cities3);

var cdbAttr = 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
  '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
  'Imagery © <a href="http://cartodb.com/attributions">CartoDB</a>',
  cdbUrl = 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
  cdbUrl2 = 'http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
  light = L.tileLayer(cdbUrl, {
    attribution: cdbAttr
  }),
  dark = L.tileLayer(cdbUrl2, {
    attribution: cdbAttr
  });

var map = L.map('map', {
  center: [39.73, -104.99],
  zoom: 10,
  layers: [light, cities1]
});

var baseLayers = {
  "Light": light,
  "Dark": dark
};

var overlays = {
  "Cities1": cities1,
  "Cities2": cities2,
  "Cities3": cities3
};

lcontrol = L.control.layers(baseLayers, overlays).addTo(map);

//make Cities1 and Cities2 mutually exclusive
//the setTimeout is needed to keep the 'overlayadd' event from firing multiple times
map.on('overlayadd', function(eo) {
  if (eo.name === 'Cities1') {
    setTimeout(function() {
      map.removeLayer(cities2)
    }, 10);
  } else if (eo.name === 'Cities2') {
    setTimeout(function() {
      map.removeLayer(cities1)
    }, 10);
  }
});