shinyFiles icon indicating copy to clipboard operation
shinyFiles copied to clipboard

hidding one shinyFilesButton with shinyjs inside renderUI call causes buttons to ask for input twice on click

Open hemstrow opened this issue 3 years ago • 4 comments

Hey there!

I noticed that if one shinyFilesButton is generated within the server part of an app and hidden via shinyjs with the hidden call inside the renderUI call only, clicking on any shiny files button in the app will cause the request to launch twice (selecting or cancelling once will immediately pull up another file browser window).

I'm not sure if this is actually unexpected behavior or if there is something I'm missing. Reproduce-able example below.

library(shiny)
library(shinyjs)
library(shinyFiles)

root <- c(wd = normalizePath("."), root = "/", home = normalizePath("~"))


ui <- fluidPage(
  useShinyjs(),
  titlePanel("File Selection: "),
  shinyFilesButton("test_input", "test", "test", multiple = TRUE),
  sidebarLayout(sidebarPanel(fluidRow(actionButton("show_it", "show second input?"), 
                                      uiOutput("input_file_selector"))),
                mainPanel(htmlOutput("fastq_files_report"))
  )
)

server <- function(input, output, session) {
  
  # one to always show
  shinyFileChoose(input, 'test_input', root=c(root))
  
  
  # generate then hide the UI input button. No reason to do it this way 
  # with this example, but I'm generating a list of buttons reactively and want to hide all of them.
  output$input_file_selector <- renderUI({
    fileinputs <- shinyFilesButton("test_input2", "test", "test", multiple = TRUE)
    shinyjs::hidden(fileinputs)
  })
  
  shinyFileChoose(input, "test_input2", root=c(root))
  
  observeEvent(input$show_it,{
    toggle("test_input2")
  })
  
} 

shinyApp(ui, server)

hemstrow avatar Aug 12 '22 01:08 hemstrow

Sorry, but I have no idea what the underlying cause is here.

vnijs avatar Aug 12 '22 07:08 vnijs

It seems like the problem also occurs if you call hidden on an a fluidRow/inputPanel/etc in the UI as well unless you then also wrap the shinyFilesButton in hidden. Something like this in the UI works ok, for example:

hidden(tags$div(id = "test_panel",
                  inputPanel(
                    column(12,
                           checkboxInput("is.paired.pre.existing", "Is your data paired-end?", value = TRUE),
                           hidden(shinyFilesButton("input1", label = "input1", multiple = TRUE, title = "input1")),
                           hidden(shinyFilesButton("input2", label = "input2", multiple = TRUE, title = "input2"))))))

but this wouldn't:

hidden(tags$div(id = "test_panel",
                  inputPanel(
                    column(12,
                           checkboxInput("is.paired.pre.existing", "Is your data paired-end?", value = TRUE),
                           shinyFilesButton("input1", label = "input1", multiple = TRUE, title = "input1"),
                           shinyFilesButton("input2", label = "input2", multiple = TRUE, title = "input2")))))

So again weird hidden interactions. I'm not sure if that helps! Like before, this actually messes up every shinyFilesButton in the app, even those that aren't hidden. Sometimes I've noticed that other buttons only double input if I've already clicked on one of the borked buttons, but I haven't figured out how to reproduce that yet.

hemstrow avatar Aug 12 '22 19:08 hemstrow