2
votes

My Shiny application updates an selectizeInput widget with values based on a leaflet marker click.

The selectizeInput widget allows multiple site selection and I managed to figure out how to update the selected list of sites based on a leaflet map marker click using the following code.

library(tidyverse)
library(shiny)
library(shinydashboard)
library(leaflet)


sensor_locations <- data.frame(site_id=c("Site1","Site2","Site3","Site4","Site5"),
                               latitude=c(-37.80079, -37.80052, -37.80230, -37.80058, -37.80063),
                               longitude=c(144.9665, 144.9641, 144.9609, 144.9646, 144.9651))

ui <- fluidPage(
  
  fluidRow(
    sidebarPanel(width = 3,
                 selectizeInput("selectedSites", "Select Sites :",
                                choices =  c("Site1","Site2","Site3","Site4","Site5"),
                                multiple = TRUE,
                                selected = c("Site1","Site2"),
                                options = list('plugins' = list('remove_button'))),
                 fluidRow(leafletOutput("sitemap"))
    ))
)


server <- function(input, output, session) {
  
  output$sitemap <- renderLeaflet({
    
    leaflet(data = sensor_locations,
            options = leafletOptions(zoomControl = FALSE)) %>%
      addProviderTiles(providers$CartoDB.Positron) %>%
      addCircleMarkers(layerId = ~site_id,
                       label = ~site_id,
                       radius= 15,
                       opacity = 1)
  })
  
  observeEvent(input$sitemap_marker_click, {
    click <- input$sitemap_marker_click
    updateSelectInput(session, "selectedSites", 
                      selected = c(input$selectedSites, click$id))
  })
  
}

shinyApp(ui = ui, server = server)

My application currently allows to add sites to the selected list on click and I now also want to allow the user to deselect sites (remove from selected list on selectizeInput box) upon clicking the leaflet markers.

1
Error in structure: object 'sensor_locations' not found please provide toy data to make the code reproducible - HubertL
@HubertL reproducible code added - z star

1 Answers

1
votes

You can do like this:

  observeEvent(input$sitemap_marker_click, {
    click <- input$sitemap_marker_click
    if(click$id %in% input$selectedSites)
      selected = input$selectedSites[input$selectedSites != click$id]
    else
      selected = c(input$selectedSites, click$id)
    updateSelectInput(session, "selectedSites", 
                      selected = selected)
  })

If you prefer more concise (and less readable) code :

  observeEvent(input$sitemap_marker_click, {
    click <- input$sitemap_marker_click
    updateSelectInput(session, "selectedSites", 
                      selected = c(click$id[!click$id %in% input$selectedSites], 
                                   input$selectedSites[input$selectedSites != click$id]))
  })