Using fileInput() to upload multiple files does not work on Mac. It works on Windows and Linux. I have also set argument multiple=T, but I am not able to select more than one file. Here is a working script.
library(shiny)
runApp(list(
ui = bootstrapPage(
tags$h2("Upload test app"),
fileInput("finput","Upload files",multiple=TRUE),
tableOutput("contents"),
),
server = function(input, output) {
output$contents <- renderTable({
input$finput})
}
))
Thanks.
Related
I am trying to build a front end using Shiny to pass some parameters to a markdown document. One parameter I want to pass is a user selected file name, including the path. I would like to use a file open type dialogue box for the user to navigate through directories and select the file. I do not need/want to actually open the file, that happens in the markdown file, I just want to pass the path and file name of the selected file out of the shiny app. I have this set up using fileInput() but of course this opens the file and makes a copy in a temp directory and the associated path is to the temp directory not the original directory. There have been some related questions about this and the only answers are that this is a security issue related to the server-based nature of shiny. Again, I don't want to open the file, just grab the original path and name. Any thoughts on how to achieve this? Here's the code stripped down to just this issue ...
library(shiny)
ui <- fluidPage(
titlePanel("Input"),
mainPanel(
fileInput(inputId = "rtffile", "Choose RTF File", accept = ".rtf", ),
)
server <- function(input, output, session) {
observe({
filename <<- input$rtffile
})
}
shinyApp(ui = ui, server = server)
In general, you can’t get a web browser to give you the path to a file on the
user’s local machine.
However, it’s possible to get a path to a file on the server.
If the server and the local machine happen to be the same, you can use e.g. shinyFiles to
pick a path:
library(shiny)
library(shinyFiles)
ui <- fluidPage(
titlePanel("Input"),
mainPanel(
shinyFilesButton("file", "Choose File", "Choose a file", multiple = FALSE),
verbatimTextOutput("file")
)
)
server <- function(input, output, session) {
roots <- getVolumes()
shinyFileChoose(input, "file", roots = roots)
file <- reactive(parseFilePaths(roots, input$file))
output$file <- renderPrint(file())
}
shinyApp(ui = ui, server = server)
Is it possible to see the changes in UI (only the UI and not server) after I make changes in my code, without having to restart the server/refresh the page? If cache needs to be cleared, can that also be done?
You could use reactiveFileReader to regularly source the code you'd save in another file, and renderUI()/uiOutput to display that dynamic UI:
app.R
library(shiny)
ui <- uiOutput("ui")
server <- function(input, output, session) {
ui <- reactiveFileReader(1000, session, "source.R", source)
output$ui <- renderUI(ui())
}
shinyApp(ui = ui, server = server)
source.R
fluidPage(
textInput("text", "text"),
textInput("text2", "text")
)
You still have to find out howto get rid of that "TRUE":
I have a PDF file that is constantly being updated and overwritten. It is saved in the www directory of the Shiny working directory. The problem is that the changes aren't being displayed in the app. The app still displays the first version of the pdf.
I originally had everything in the UI. I used tags$iframe in the ui.r code with the src pointing directly to the pdf file in the www directory.
Then I noticed that the pdf wasn't updating, so I tried to make an action button that when pushed would run the tags$iframe and display the pdf. This did not solve the problem. The updates in the pdf file are still not being displayed.
First attempt with everything in the UI
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h3("Title")
),
mainPanel(
tabsetPanel(
tabPanel("Tab 1",
tags$iframe(style="height:1200px; width:100%; scrolling=yes",
src="PDF1.pdf"))
)
)
)
)
server <- function(input, output,session){
}
shinyApp(ui, server)
Second attempt with the action button
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h3("Title")
),
mainPanel(
tabsetPanel(
tabPanel("Tab1",
sidebarLayout(
sidebarPanel(
actionButton("refresh_1", "Refresh PDF")
),
mainPanel(
uiOutput("Show_PDF1")
)
)
)
)
))
)
server <- function(input, output,session){
observeEvent(input$refresh_1, {
output$Show_PDF1 <- renderUI({
tags$iframe(style="height:1200px; width:100%; scrolling=yes", src="PDF1.pdf")
})
})
}
shinyApp(ui, server)
I am hosting the app on a non pro version of shiny server, and accessing it with chrome. To recreate the problem you can put any pdf file into the /srv/shiny-server/www directory with the name PDF1.pdf, and access the app. Then overwrite PDF1.pdf with another pdf file and run the app again. You will see that the app is still displaying the original PDF1.pdf file.
I am finally trying to make a Shiny app. I am trying to upload a .xlsx file to the app, and then apply some analysis and download the output as a separate .xlsx file. The code for analysis and taking output works when run directly outside Shiny and I use it on daily, so I am simply trying to call it via source and save the duplicated work. Here is what I am trying with Shiny.
I was having problems in calling the file from the W2S.R script, while avoiding errors. I found a way to avoid the errors. The below code is a barebones model of that. However, now I cannot get the actual input to work (Output works fine, one table output on-screen and one XLSX output off-screen).
I am using W2S <- input$W2S1 inside W2S.R script, but it is not recognising the variable input, which it does if used in the server function directly. How do I get it to work inside the script? Or is there any other workaround?
library(shiny)
ui <- fluidPage(
titlePanel(h1("Goods In Transit Analysis", align="center")),
sidebarLayout(
sidebarPanel(
fileInput("W2S1", label="Select GIT W2S file")
),
mainPanel(
tableOutput("contents")
)
)
)
server <- function(input, output) {
output$contents <- renderTable(if(is.null(input$W2S1)){return(NULL)}
else{source("./W2S.R")})
}
shinyApp(ui = ui, server = server)
I will update once I get the input to work. Please help.
EDIT: Made some progress, as noted above. So updated the new code.
Finally nailed it. I needed an observe function and use the $datapath argument.
library(shiny)
ui <- fluidPage(
# Application title
titlePanel(h1("Goods In Transit Analysis", align="center")),
# Sidebar iputs
sidebarLayout(
sidebarPanel(
fileInput(inputId="W2S", label="Select GIT W2S file")
),
# On Screen output
mainPanel(
h3(textOutput("filePath")),
tableOutput("contents")
)
)
)
# Underlining code for output
server <- function(input, output) {
observe({
source("./Code/W2S.R")
W2S <- input$W2S
output$contents <- renderTable(if(is.null(W2S)){return(NULL)}
else{W2S_F(W2S$datapath)})
})
}
# Run the application
shinyApp(ui = ui, server = server)
I want to make a Shiny App in which the user can press an actionbutton which would then trigger some code on the server side creating a file in the www folder and then opens/downloads the file.
Suppose the file is test.txt (in my case it would be a variety of R, Excel, and exe files which will be copied from different folders on a drive to the www folder).
My first try was to use the actionbutton with the onclick option as shown below
ui <- fluidPage(
actionButton("showtxt", "Show/Download File", onclick = "window.open('test.txt')")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
})
}
shinyApp(ui=ui,server=server)
But this doesn't work since the onclick action is done before the observevent is evaluated.
I then tried to call a function inside to the onclick option as shown below
CreateFileAndLink <- function(){
write.table(c("Test"), file = "www/test.txt")
return("window.open('test.txt')")
}
ui <- fluidPage(
actionButton("showtxt", "Show/Download File", onclick = CreateFileAndLink())
)
server <- function(input, output, session){}
shinyApp(ui=ui,server=server)
This works but has the downside that now the file is created when upon opening the Shiny App as opposed to creating the file when the user clicks the actionbutton. This is very inefficient if I were to use this piece of code multiple times in an App with relatively large files.
Maybe it is possible to make sure that the observevent is executed before the onclick-action, or maybe use the onclick option on the server side.
Any help would be greatly appreciated!
Cheers
UPDATE:
I found out that the great shinyjs package by Dean Attali contains a onclick function that might be of help here. I tried to run the code below but it didn't work :/
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("showtxt", "Show/Download File")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
# Call Onclick
onclick("showtxt", "window.open('test.txt')")
})
}
shinyApp(ui=ui,server=server)
I found a solution using the onclick function from the shinyjs package.
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
actionButton("showtxt", "Show/Download File")
)
server <- function(input, output, session){
observeEvent(input$showtxt,{
# Write some text
write.table(c("Test"), file = "www/test.txt")
})
# Call Onclick
onclick("showtxt", runjs("window.open('test.txt')"))
}
shinyApp(ui=ui,server=server)