I am building a rudimentary shiny app. First, I created a data frame 'x' and saved it in my working directory (where my code for my app is):
x <- data.frame(a = 1:4, b = 2:5)
write.csv(x, 'x.csv', row.names = F)
In my shiny app I'd like to:
Upload file 'x.csv'
Click my action button 'Click Here' and run a few commands upon clicking it.
Get a message printed in the Shiny app itself: "Load a file!" if I click on my button "Click here" after forgetting to upload the file first.
My code works, but I can't figure out how to make my message appear.
Thank you so much for your suggestions!
My code:
library(shiny)
ui <- fluidPage(
br(),
# User should upload file x here:
fileInput("file_x", label = h5("Upload file 'x'!")),
br(),
# Users clicks the button:
actionButton("do_it", "Click Here"),
br(),
# Print last value of the button 'do_it':
verbatimTextOutput("print_action")
)
server <- function(input, output, session) {
observeEvent(input$do_it, {
# Just a check of my button's actions:
output$print_action <- renderPrint({input$do_it})
# Validating the input - next 5 lines are not working:
# validate(
# need(
# try(is.null(input$file_x), "Load a file!")
# )
# )
# Reading in the file:
fileData <- reactive({
infile <- input$file_x
if (is.null(infile)) {
return(NULL)
}
read.csv(infile$datapath)
})
x <- fileData()
# Writing out the same file - but under a different name:
filename <- paste0("x", input$do_it, ".csv")
write.csv(x, file = filename, row.names = FALSE)
})
}
shinyApp(ui, server)
This isn't too complicated with shinyjs. You need to include a hidden p element in the ui and unhide it when the file hasn't been selected yet. Code I've added is followed with ########## (10 #s)
library(shiny)
library(shinyjs) ##########
ui <- fluidPage(
# make shinyjs work in the UI ##########
useShinyjs(), ##########
br(),
# User should upload file x here:
fileInput("file_x", label = h5("Upload file 'x'!")),
br(),
# Users clicks the button:
actionButton("do_it", "Click Here"),
hidden(p("Select a file first", ##########
id = "p_nofile", ##########
style = "font-weight:bold;color:red;")), ##########
br(),
# Print last value of the button 'do_it':
verbatimTextOutput("print_action")
)
server <- function(input, output, session) {
observeEvent(input$do_it, {
# If there file_x input is NULL, show the message in p_nofile ##########
if (is.null(input$file_x)){ ##########
shinyjs::show("p_nofile") ##########
} else{ ##########
# if we have a file selected, hide the p_nofile message ##########
shinyjs::hide("p_nofile") ##########
# Just a check of my button's actions:
output$print_action <- renderPrint({input$do_it})
# Validating the input - next 5 lines are not working:
# validate(
# need(
# try(is.null(input$file_x), "Load a file!")
# )
# )
# Reading in the file:
fileData <- reactive({
infile <- input$file_x
if (is.null(infile)) {
return(NULL)
}
read.csv(infile$datapath)
})
x <- fileData()
# Writing out the same file - but under a different name:
filename <- paste0("x", input$do_it, ".csv")
write.csv(x, file = filename, row.names = FALSE)
} ##########
})
}
shinyApp(ui, server)
nutterb, thank you very much!
I tried your code. It's working, but I have two questions:
Is it possible to hide the (ui) text "Select a file first" - only after the user tries to click the button "Click Here" without uploading the file first?
Is it possible to get rid of the text "Select a file first" after the user uploaded the file?
Thanks again!
I think my code sample already does that. This is what the app looks like when I first run it on my machine (I've made the background gray so you can see where the images end):
Then after clicking the button without selecting a file.
And then after clicking the button after selecting a file.
Actually, it almost does what is desired, but not 100%. Assume I forget to upload a file and click on the "Click Here" button. Then I get the message. But once I upload the file, the message is still there - until I click on "Click Here" button. It'd be nice if it disappeared after the data file has been uploaded.