Leaflet and Mapbox: Buttons not working when added via Javascript -


anyone know why that, when clicked, buttons not add or remove overlays map? full plnkr here

the html

<div id="togglebuttons" style="display: none">  <button id="add">add overlays</button>  <button id="remove">remove overlays</button> </div> 

the javascript

l.control.groupedlayers.include({ addoverlays: function () {     (var in this._layers) {         if (this._layers[i].overlay) {             if (!this._map.haslayer(this._layers[i].layer)) {                 this._map.addlayer(this._layers[i].layer);             }         }     } }, removeoverlays: function () {     (var in this._layers) {         if (this._layers[i].overlay) {             if (this._map.haslayer(this._layers[i].layer)) {                 this._map.removelayer(this._layers[i].layer);             }         }     }  } });  var control = new l.control.groupedlayers(exampledata.basemaps, { 'landmarks': {     'cities': exampledata.layergroups.cities,     'restaurants': exampledata.layergroups.restaurants }, 'random': {     'dogs': exampledata.layergroups.dogs,     'cats': exampledata.layergroups.cats } }).addto(map);  l.domevent.addlistener(l.domutil.get('add'), 'click', function () { control.addoverlays(); });  l.domevent.addlistener(l.domutil.get('remove'), 'click', function () { control.removeoverlays(); }); 

and added mapbox legendcontrol.addlegend method (from mapbox api documentation)

map.legendcontrol.addlegend(document.getelementbyid('togglebuttons').innerhtml); 

although buttons shown in map, click properties not working. clues? thanks!

you're not 'adding' buttons javascript, you're making copy of them , placing copy legendcontrol. actual buttons eventhandlers still present in dom hidden because you've added display: none inline style. want select buttons , remove them body:

var buttons = document.getelementbyid('togglebuttons'); document.body.removechild(buttons); 

then can add them legend , attach eventhandlers:

var legendcontrol = l.mapbox.legendcontrol().addto(map);  legendcontrol.addlegend(buttons.innerhtml);  l.domevent.addlistener(l.domutil.get('add'), 'click', function () {     control.addoverlays(); });  l.domevent.addlistener(l.domutil.get('remove'), 'click', function () {     control.removeoverlays(); }); 

working example on plunker: http://plnkr.co/edit/7pdkrzbs7re1yshkzsls?p=preview

ps. i'm quite baffled why abuse mapbox's legend control class add 2 buttons. if need custom control can create 1 using leaflet's l.control class. spares loading legend control class you're not using, bloat.

edit: promised in comments below example of rolling solution own custom control. i'll explain more throughout comments in code general idea take basic l.control interface , adding functionality , dom generation it:

// create new custom control class extended l.control l.control.toggle = l.control.extend({      // have default options, can change/set     // these when intializing control     options: {         position: 'topright',         addtext: 'add',         removetext: 'remove'     },      initialize: function (control, options) {         // add options instance         l.setoptions(this, options);         // add reference layers in layer control         // added constructor upon intialization         this._layers = control._layers;     },      onadd: function (map) {         // create container         var container = l.domutil.create('div', 'control-overlaystoggle'),             // create add button classname, append container             addbutton = l.domutil.create('button', 'control-overlaystoggle-add', container),             // create remove button classname, append container             removebutton = l.domutil.create('button', 'control-overlays-toggleremove', container);          // add texts options buttons         addbutton.textcontent = this.options.addtext;         removebutton.textcontent = this.options.removetext;          // listen click events on button, delegate methods below         l.domevent.addlistener(addbutton, 'click', this.addoverlays, this);         l.domevent.addlistener(removebutton, 'click', this.removeoverlays, this);          // make sure clicks don't bubble map         l.domevent.disableclickpropagation(container);          // return container         return container;     },      // methods add/remove extracted groupedlayercontrol     addoverlays: function () {         (var in this._layers) {             if (this._layers[i].overlay) {                 if (!this._map.haslayer(this._layers[i].layer)) {                     this._map.addlayer(this._layers[i].layer);                 }             }         }     },      removeoverlays: function () {         (var in this._layers) {             if (this._layers[i].overlay) {                 if (this._map.haslayer(this._layers[i].layer)) {                     this._map.removelayer(this._layers[i].layer);                 }             }         }     }  }); 

now can use new control follows:

// create new instance of layer control , add map var layercontrol = new l.control.groupedlayers(baselayers, overlays).addto(map);  // create new instance of toggle control // set layercontrol , options parameters // , add map var togglecontrol = new l.control.toggle(layercontrol, {     position: 'bottomleft',     addtext: 'add overlays',     removetext: 'remove overlays' }).addto(map); 

i know, quick , dirty should give decent idea of can l.control class in general.

here's working example on plunker: http://plnkr.co/edit/7pdkrzbs7re1yshkzsls?p=preview

and here's reference l.control: http://leafletjs.com/reference.html#control


Comments