Skip to content
Advertisement

Leaflet map with embedded Bootstrap Switch toggle

I am trying to add a bootstrap switch inside my leaflet.js map.

So far I have a working button (see snippet) but I want to use a switch instead.

See attached image:

enter image description here

So far it is a complete failure.

Among the things I have tried is the code below (which obviously does not work):

 var customControl_2 =  L.Control.extend({        
      options: {
        position: 'topright'
      },

      onAdd: function (map) {
        var container = L.DomUtil.create('input', 'mySwitch');

        container = $("[class='mySwitch']").bootstrapSwitch({})

        //container.onclick = function(){
        //  console.log('buttonClicked');
        //}


        return container;
      }
    });
    map.addControl(new customControl_2());

Does anyone know how this should work please? As always, any help is greatly appreciated. If the same toggle switch can be achieved in some other way (ie without bootstrap) that is also going to be fine.

Many thanks!

<!DOCTYPE html>
<html>

<head>

<title>Leaflet</title>

<meta charset="utf-8" />

<!--jquery -->
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>

<!-- bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> 

<!-- bootstrap switch -->
<link rel="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap3/bootstrap-switch.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/js/bootstrap-switch.js"></script> 

<!--d3 -->
<script src='https://d3js.org/d3.v4.min.js'></script>

<!-- leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>



<style>
    html,
    body {
        height: 100%;
        margin: 0;
    }

    #map {
        width: 600px;
        height: 400px;
    }

</style>


</head>

<body>

<div id='map'></div>

<script type="text/javascript">
    var map = L.map('map', {
        minZoom: 0,
    }).setView([37, -103], 3);

    var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
        attribution: "CartoDB"
    }).addTo(map);


    // Toggle button to turn layers on and off
    var customControl = L.Control.extend({
        options: {
            position: 'topright'
        },

        onAdd: function(map) {
            var container = L.DomUtil.create('input');
            container.type = "button";
            container.title = "Some title";
            container.value = "Off";

            container.style.backgroundColor = 'white';
            container.style.backgroundSize = "80px 30px";
            container.style.width = '80px';
            container.style.height = '30px';


            function toggle(button) {
                if (button.value == "Off") {
                    button.value = "On"
                    button.innerHTML = "On"
                    removeLayers();
                } else if (button.value == "On") {
                    button.value = "Off"
                    button.innerHTML = "Off"
                    addLayers();
                }
            }

            container.onclick = function() {
                toggle(this);
                console.log('buttonClicked');
            }


            return container;
        }
    });
    map.addControl(new customControl());

</script>



</body>

</html>

Advertisement

Answer

  1. The $("[class='mySwitch']") finds Elements based on the string selector. You have to adjust the Bootstrap Switch example to your usage. In your case, you do not need a selector but you can directly pass the HTML Element you created, so that it is wrapped by jQuery and can be transformed by Bootstrap Switch: $(container).bootstrapSwitch({})

  2. Do not try to transform your Control container directly, but embed a child checkbox input into that container:

    var container = L.DomUtil.create('div');
    // Use a child input.
    var input = L.DomUtil.create('input');
    input.type = "checkbox";
    // Insert the input as child of container.
    container.appendChild(input);
    // Transform the input, not the container.
    $(input).bootstrapSwitch({});
  1. You have a typo in:
<link rel="https:....css">

…should be:

<link rel="stylesheet" href="https:....css">

Live result:

var map = L.map('map', {
  minZoom: 0,
}).setView([37, -103], 3);

var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
  attribution: "CartoDB"
}).addTo(map);


// Toggle button to turn layers on and off
var customControl = L.Control.extend({
  options: {
    position: 'topright'
  },

  onAdd: function(map) {
    var container = L.DomUtil.create('div');
    // Use a child input.
    var input = L.DomUtil.create('input');
    input.type = "checkbox";
    input.title = "Some title";
    input.value = "Off";
    // Insert the input as child of container.
    container.appendChild(input);

    jQuery(input).bootstrapSwitch({
      // http://bootstrapswitch.site/options.html
      onSwitchChange: function(event) {
        console.log('buttonClicked', event.target.checked);
      }
    });

    return container;
  }
});
map.addControl(new customControl());
html,
body,
#map {
  height: 100%;
  margin: 0;
}
<!--jquery -->
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>

<!-- bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!--script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script-->

<!-- bootstrap switch -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap3/bootstrap-switch.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/js/bootstrap-switch.js"></script>

<!-- leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>

<div id='map'></div>
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement