I would like to add a toggle control/switch for basemaps to my code. I tried something similar to this:


but it does not work in combination with CreateLayer.

I also found this:


where leaflets L.Control was used. But due to my limited JavaScript knowledge, I cannot get it to work... :/

NEW CODE (with layer selector and basemap selector):

    <div id="map"></div>
    <div style="display: block;" class="cartodb-fullscreen"><a href="#" target="_blank" title="Vollbild (empfohlen f&uuml;r mobile Ger&auml;te)"></a></div>
    <div id="cartocss" class="layer_selector"><div class="close">×</div>
        <p id="js-category-selector">XXXX</p>
        <ul class="LayerSelector-list">
            <li data="1" class="button noleg selected">XXXX
            <li data="2" class="button">XXXX
            <li data="4" class="button">XXXX
            <li data="3" class="button">XXXX
    <div id='selector_menu'>
        <select id="selector">
            <option value="StreetMap">Stra&szlige</option>
            <option value="AerialMap">Satellit</option>  
    <!-- include cartodb.js library -->
    <script src="http://libs.cartocdn.com/cartodb.js/v3/3.15/cartodb.js"></script>
    <!-- Place your code in the script tags below -->
        $( document ).ready(function() {
            $( "#js-category-selector" ).click(function() {
                $( '.layer_selector' ).toggleClass( "is-active" );
    var $this = $(this);


    if ($this.hasClass('+')) {
        } else {
    <script type="text/javascript">

    function main() {
        "use strict";
        var map;
        //  center and zoom level
        var options = {
            center: [48.3,9.8], // Distribution area
            zoom: 9,
            minZoom: 3,
            maxZoom: 18,
            scrollWheelZoom: false        
        // define map object
        var map_object = new L.Map('map', options);

        var densityLegend = new cdb.geo.ui.Legend.Density({
        // Put optional legend for noleg items here

        // Hide legend for items with class noleg

        var densityAltLegend = new cdb.geo.ui.Legend.Density({
            title: "Legende",
            left: "Weniger", right: "Mehr", colors: [ "#FFEDA0", "#FEB24C", "#F03B20" ]
        // Hide legend for items with class noleg at start
        // Create layer selector
        function createSelector(layer,num,unfaellemap) {
            for (var i = 1; i < layer.getSubLayerCount(); i++) {
                if (i === num) {
          } else {
            if (unfaellemap){
        } else {

        // add default basemap
        var basemap1 = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
            type: 'map',
            ext: 'jpg',
            subdomains: '1234',
            attribution: '<a href="http://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        // add new basemap option
        var basemap2 =  L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
            attribution: '&copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'

        // For storing sublayer outside of createlayer
        // var sublayers;

        // Add data layer to your map
        cartodb.createLayer(map_object,'https://documentation.cartodb.com/api/v2/viz/236ecca6-8877-11e5-8a51-0ef7f98ade21/viz.json', {
            searchControl: false, legends: false, cartodb_logo: false, tooltip: true, infowindow: true, zoomControl: true, scrollwheel: false, layer_selector: false, layerIndex:1 })
            .on('done', function (layer){
                var sublayer0 = layer.getSubLayer(0).setInteraction(true);
                layer.getSubLayer(0).infowindow.set('template', $('#infowindow_template').html());
                var sublayer1 = layer.getSubLayer(1);
                var sublayer2 = layer.getSubLayer(2);
                var sublayer3 = layer.getSubLayer(3);
                var sublayer4 = layer.getSubLayer(4);
                // hide sublayer1
                // define ZIndex of the CartoDB layer
                // define basemap options
                var LayerActions = {
                StreetMap: function(){
                // if map_object has already a basemap, remove it and add a new one
                    if (map_object.hasLayer(basemap1) || (map_object.hasLayer(basemap2))){
                return true;
                // if map_object has already a basemap, remove it and add a new one
                AerialMap: function(){
                    if (map_object.hasLayer(basemap1) || (map_object.hasLayer(basemap2))){
                return true;
            $('#selector').change(function() {
            $("li").on('click', function(e) {
                var num = +$(e.target).attr('data');
            $( '.button' ).removeClass('selected');
            .error(function(err) {
                console.log("error: " + err);
    window.onload = main;

2 Answers 2


To toggle basemaps with the cartoDB createLayer() method you could use the leaflet addLayer(), removeLayer(), hasLayer() methods in order to add or remove the basemaps layers.

Here you can see an example of how to toggle basemaps with the createLayer() method.


In the example a HTML dropdown menu is used to switch the basemap layers.

  • Great! This actually worked - thanks a lot! I got one small problem though: As soon as I switch the basemaps and start selecting different layers with data in the layer selector again, it gets pretty slow. Data loads forever, sometimes it stalls completely. Could you look over my code again please? I edited my original post. Thanks a lot! Nov 20, 2015 at 1:12
  • I cleaned up the code a bit. Now it works. Thanks again. Nov 20, 2015 at 12:26
  • Happy to hear that it works! :)
    – oriolbx
    Nov 20, 2015 at 16:34
  • @schwaebische do you mind marking the question as answered?
    – Jorge Sanz
    Jun 5, 2016 at 21:53

Here's a function to remove the current basemap from the bottom layer, then add a new basemap and move it to the bottom layer. Careful, this is hot!

var basemap1 = L.tileLayer('http://{s}.tile.thunderforest.com/spinal-map/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://www.thunderforest.com/">Thunderforest</a>, &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',maxZoom: 11});

var basemap2 = L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {attribution: 'Stamen'});

function setBasemap(basemap) {
  if (currentBasemap) {
  currentBasemap = basemap;
var currentBasemap = basemap1; // default map
setBasemap(currentBasemap); // Init

Then add the following in a click event to swap in a basemap:


Add a new var for each additional basemap. (basemap3, basemap4, etc.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.