36

So I'm trying to make a shiny app where I have a button which only shows up if files have been uploaded; for this im using conditionalPanel.

ui.R:

require(shiny)
shinyUI(pageWithSidebar(
  headerPanel("My App"),

  sidebarPanel(
    fileInput("files", "Choose file"),
    conditionalPanel(
      condition = "input.files",
      actionButton("submitFiles", "Submit files for processing"))),

  mainPanel(h3("Nothing to see here"))
))

I don't think there's anything to care about in my server.R, since the above example doesn't do anything. With the above condition, the button never shows up, i.e. the condition is never true.

Some things I've tried for my condition are input.files.length > 0, input.files.size() > 0, both of which result in the button being present before I upload a file. I'm guessing this is because input$files is an empty data.frame before choosing files, and so has a non-zero length/size, is that right?

What condition can I use to hide the button until at least one file is done uploading?

I think another option would be to replace conditionalPanel with uiOutput, and call renderUI({actionButton(...)}) inside of an observe/isolate block in server.R which is watching input.files (if (nrow(input$files) < 1) return()); is that the only way? If I can do this either way, what would make me pick one or the other (beyond conditionalPanel resulting in less code)?

Spacedman
  • 92,590
  • 12
  • 140
  • 224
ClaytonJY
  • 1,244
  • 10
  • 21

2 Answers2

55

You have to make a reactive output returning the status of the uploading and set the option suspendWhenHidden of this output to FALSE.

More precisely, in server.R you surely have a reactive function, say getData() to make a dataframe from the uploaded file. Then do this:

  getData <- reactive({
    if(is.null(input$files)) return(NULL)
    ......
  })
  output$fileUploaded <- reactive({
    return(!is.null(getData()))
  })
  outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)

And in ui.R you can use conditionalPanel() by doing:

conditionalPanel("output.fileUploaded",
   ......
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • 1
    aha, I didn't even know `outputOptions()` existed! That's a tricky way to 'hide' something in your `output` list, but it works. – ClaytonJY Feb 11 '14 at 20:06
  • 8
    It seems that something has changed and now one has to do `"output.fileUploaded == true"`. – Stéphane Laurent Feb 01 '17 at 15:10
  • 1
    Since all-caps `TRUE` is normally used in R, I feel like I should point out that the lowercase `true` used in `"output.fileUploaded == true"` is correct. – userABC123 May 09 '20 at 20:37
0

Under R 4.2.2, I have to changed it to "output.fileUploaded == 0" to make it work. I do not know why.

Steven Ge
  • 61
  • 5