programatically toggle a shinyWidgets::dropdown()

I want to create a button dropdown. I'd love to use shinyWidgets::dropdownButton(), but that one has a problem, because it doesn't allow shinyWidgets::pickerInput() to be inside it. It is recommended to use shinyWidgets::dropdown() to be used with the pickerInput.

The problem I'm having is that I'm not able to programatically toggle the dropdown:

library("shiny")
library("shinyWidgets")

ui <- fluidPage(
  fluidRow(
    column(6,
      dropdown(
        actionButton("but1", "Close"),
        label = "Drop 1",
        inputId = "drop1"
      )
    ),
    column(6,
      dropdownButton(
        actionButton("but2", "Close"),
        label = "Drop 2",
        inputId = "drop2"
      )
    )
  )
)

server <- function(input, output, session) {
  observeEvent(input$but1, {
    toggleDropdownButton("drop1", session)
  })
  observeEvent(input$but2, {
    toggleDropdownButton("drop2", session)
  })
}

shinyApp(ui, server)

Is there some way to do it?
Thanks

Hi @JonnyRobbie. The dropdown defined a behaviour that will be closed when clicking outside of it. So, you can trigger the html click event to close the dropdown by session$sendCustomMessage and Shiny.addCustomMessageHandler.

library("shiny")
library("shinyWidgets")

ui <- fluidPage(
  tags$head(
    tags$script("Shiny.addCustomMessageHandler('close_drop1', function(x){
                  $('html').click();
                });")
  ),
  fluidRow(
    column(6,
           dropdown(
             actionButton("but1", "Close"),
             label = "Drop 1",
             inputId = "drop1"
           )
    ),
    column(6,
           dropdownButton(
             actionButton("but2", "Close"),
             label = "Drop 2",
             inputId = "drop2"
           )
    )
  )
)

server <- function(input, output, session) {
  observeEvent(input$but1, {
    session$sendCustomMessage("close_drop1", "")
  })
  observeEvent(input$but2, {
    toggleDropdownButton("drop2", session)
  })
}

shinyApp(ui, server)

@raytong

That's a great workaround man! I had been working on this for a while and couldn't get it to work. Great job!

I do however find it weird that this option would not be integrated in the dropdown as it is in the dropdownButton. Do you know why this would be the case? Maybe they just forgot to implement it... The package readme does mention the inputId is used for that, but doesn't specify how to do it, so yours is now the best solution.

Thanks again

PJ

1 Like