3

I would like to display a conditional panel in my map when I click on a circle, and this conditional panel must disappear if I click outside a circle, but it does not appear and I don't know why.

I think it's about reactive values (one more time).

If any idea, please tell me.

Thank you very much, this is a reproducible example (thanks to SymbolixAU) :

ui :

library(shiny)
library(leaflet)

ui <- fluidPage(
  leafletOutput("mymap",width="100%",height="750px"), 

  conditionalPanel(

    condition = "output.COND == '2'",

    fluidRow(

      absolutePanel(id = "cond_panel", 
                    class = "panel panel-default", 
                    fixed = TRUE,
                    draggable = TRUE, 
                    top = "auto", 
                    left = 200, 
                    right = "auto", 
                    bottom = 0,
                    width = 400, 
                    height = 400,
                    fluidRow(

                    ) # e. of fluidRow(

       ) # # e. of absolutePanel

    ) # e. of fluidRow

  ) # e. of conditionalPanel

) # e. of fluidPage

and the server :

server <- function(input, output){

  rv <- reactiveValues()
  rv$myDf <- NULL
  rv$cond <- NULL

  cities <- read.csv(textConnection("
                                City,Lat,Long,Pop
                                Boston,42.3601,-71.0589,645966
                                Hartford,41.7627,-72.6743,125017
                                New York City,40.7127,-74.0059,8406000
                                Philadelphia,39.9500,-75.1667,1553000
                                Pittsburgh,40.4397,-79.9764,305841
                                Providence,41.8236,-71.4222,177994
                                "))
  cities$id <- 1:nrow(cities) 

  output$mymap <- renderLeaflet({
    leaflet(cities) %>% addTiles() %>%
      addCircles(lng = ~Long, lat = ~Lat, weight = 1,
             radius = ~sqrt(Pop) * 30, popup = ~City, layerId = ~id)
  })

  observeEvent(input$mymap_click, {

    print("map clicked")
    rv$cond <- "1"
    print(paste("Value rv$cond = ", rv$cond))
    output$COND <- reactive({rv$cond})
    leafletProxy("mymap")

  }) # e. of observeEvent

  observeEvent(input$mymap_shape_click, {

    print("shape clicked")
    rv$cond <- "2"
    print(paste("Value rv$cond = ", rv$cond))
    output$COND <- reactive({rv$cond})
    leafletProxy("mymap")

  }) # e. of observeEvent

} # e. of server
Mickey_NC
  • 269
  • 1
  • 5
  • 17

2 Answers2

3

I'm going to propose a slightly different approach that uses library(shinyjs) to use javascript to control whether the panel is hidden or not.

In this example I've created a hidden div element (i.e., the panel will start hidden when the app opens). Then the 'div' is shown when the circle is clicked, and hidden again when the map is clicked.

This answer is inspired by @Daattali's answer here (he's the author of library(shinyjs).

library(shiny)
library(leaflet)
library(shinyjs)

ui <- fluidPage(
    useShinyjs(),     ## Call to use shinyJS
    leafletOutput("mymap",width="100%",height="750px"), 

    #conditionalPanel(

        #condition = "output.COND === '2'",
    hidden( 
        div(id = "conditionalPanel",
            fluidRow(

                absolutePanel(id = "cond_panel", 
                            class = "panel panel-default", 
                            fixed = TRUE,
                            draggable = TRUE, 
                            top = "auto", 
                            left = 200, 
                            right = "auto", 
                            bottom = 0,
                            width = 400, 
                            height = 400,
                            fluidRow(

                    ) # e. of fluidRow(

                ) # # e. of absolutePanel

            ) # e. of fluidRow
        )
    )

#   ) # e. of conditionalPanel

) # e. of fluidPage


server <- function(input, output){

    rv <- reactiveValues()
    rv$myDf <- NULL
    rv$cond <- NULL

    cities <- read.csv(textConnection("
                        City,Lat,Long,Pop
                        Boston,42.3601,-71.0589,645966
                        Hartford,41.7627,-72.6743,125017
                        New York City,40.7127,-74.0059,8406000
                        Philadelphia,39.9500,-75.1667,1553000
                        Pittsburgh,40.4397,-79.9764,305841
                        Providence,41.8236,-71.4222,177994
                        "))
    cities$id <- 1:nrow(cities) 

    output$mymap <- renderLeaflet({
        leaflet(cities) %>% addTiles() %>%
            addCircles(lng = ~Long, lat = ~Lat, weight = 1,
                                 radius = ~sqrt(Pop) * 30, popup = ~City, layerId = ~id)
    })

    observeEvent(input$mymap_click, {

        shinyjs::hide(id = "conditionalPanel")
        print("map clicked")
        rv$cond <- "1"
        print(paste("Value rv$cond = ", rv$cond))
        output$COND <- reactive({rv$cond})
        leafletProxy("mymap")

    }) # e. of observeEvent

    observeEvent(input$mymap_shape_click, {

        shinyjs::show(id = "conditionalPanel")
        print("shape clicked")
        rv$cond <- "2"
        print(paste("Value rv$cond = ", rv$cond))
        output$COND <- reactive({rv$cond})
        leafletProxy("mymap")

    }) # e. of observeEvent

} # e. of server

shinyApp(ui, server)
Community
  • 1
  • 1
SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
  • You're the best SymbolixAU, it works great ! I would never have found how to do without your help, it's the third time you help me since yesterday. Thank you so much, have a great day. – Mickey_NC Jan 20 '17 at 02:01
  • @Mickey_NC - no problem! feel free to accept / 'tick' the answer if it solves your problem ! – SymbolixAU Jan 20 '17 at 02:12
  • This answer is awesome; still relevant 4 years later! Far superior to using shiny::conditionalPanel(). – awags1 Aug 02 '21 at 17:14
0

Just use the absolutePanel inside a conditionalPanel whose condition you reset based on user input.

ProgSnob
  • 483
  • 1
  • 9
  • 20