3

I would like to use the leaflet easyButton plugin to control the layers shown instead of the built in layer controls. Unfortunately I do not know JS, and have spent several hours trying to make sense of the leafletJS documentation to find the correct way to do this.

Here is a slimmed down version of the code I'm attempting. The onClick is clearly working since the alerts happen, but nothing changes with the layer being shown.

Each button should show ONLY that one layer and none of the others (as opposed to allowing multiple layers to be seen at once).

library(tidyverse)
library(sf)
library(tigris)
library(leaflet)

statemap <- states(cb = T)


statemap <- statemap %>% 
  filter(GEOID < 60) %>% 
  shift_geometry(geoid_column = "GEOID") %>% 
  st_transform("EPSG:4326")

leaflet(statemap) %>% 
  addPolygons(weight = 1.25, color = "#000000", opacity = 1,#444444
              fillColor = "green",
              layerId = "green") %>% 
   addPolygons(weight = 1.25, color = "#000000", opacity = 1,#444444
              fillColor = "red",
              layerId = "red") %>% 
   addPolygons(weight = 1.25, color = "#000000", opacity = 1,#444444
              fillColor = "yellow",
              layerId = "yellow") %>% 
  addEasyButtonBar(easyButton(icon = "fa-globe", title = "Drinking Water Standard",
                onClick = JS("function(btn, map) {
                             alert(\"Green\");
                             map.clearLayers();
                             map.addLayer('green');
                }")), 
    easyButton(icon = "fa-crosshairs", title = "Groundwater Standard",
                onClick = JS("function(btn, map) {
                             alert(\"Yellow\");
                             map.clearLayers();
                             map.addLayer('yellow');
                }")),
    easyButton(icon = "fa-globe", title = "Surface Water Standard",
                onClick = JS("function(btn, map) {
                             alert(\"Red\");
                             map.clearLayers();
                             map.addLayer('red');
                }"))) 
Progman
  • 16,827
  • 6
  • 33
  • 48
jzadra
  • 4,012
  • 2
  • 26
  • 46

1 Answers1

4

You could use the existing functionality of the baseGroups argument in the addLayersControl() function and map the onClick event to the Easy Buttons.

The final onRender() function simply hides this layer control panel so people use the easy buttons instead.

Working example: https://rpubs.com/Jumble/leaflet_easybuttons_layer_control

library(tidyverse)
library(sf)
library(tigris)
library(leaflet)

statemap <- states(cb = T)


statemap <- statemap %>% 
  filter(GEOID < 60) %>% 
  shift_geometry(geoid_column = "GEOID") %>% 
  st_transform("EPSG:4326") 

leaflet(statemap) %>% 
  addPolygons(weight = 1.25, color = "#000000", opacity = 1,#444444
              fillColor = "green",
              group = "green") %>% 
  addPolygons(weight = 1.25, color = "#000000", opacity = 1,#444444
              fillColor = "red",
              group = "red") %>% 
  addPolygons(weight = 1.25, color = "#000000", opacity = 1,#444444
              fillColor = "yellow",
              group = "yellow") %>% 
  addLayersControl(baseGroups = c("green", "red", "yellow"), options=layersControlOptions(collapsed = F)) %>%
  addEasyButtonBar(easyButton(icon = "fa-globe", title = "Drinking Water Standard",
                              onClick = JS("function(btn, map) {
                     
                             let layerControlElement = document.getElementsByClassName('leaflet-control-layers')[0];
                             layerControlElement.getElementsByTagName('input')[0].click();

                }")), 
                   easyButton(icon = "fa-crosshairs", title = "Groundwater Standard",
                              onClick = JS("function(btn, map) {

                             let layerControlElement = document.getElementsByClassName('leaflet-control-layers')[0];
                             layerControlElement.getElementsByTagName('input')[1].click();

                }")),
                   easyButton(icon = "fa-globe", title = "Surface Water Standard",
                              onClick = JS("function(btn, map) {
                              
                             let layerControlElement = document.getElementsByClassName('leaflet-control-layers')[0];
                             layerControlElement.getElementsByTagName('input')[2].click();

                }"))) %>%
  htmlwidgets::onRender("
    function(el, x) {
        document.getElementsByClassName('leaflet-control-layers')[0].style.display = 'none';
    }")
Jumble
  • 1,128
  • 4
  • 10