The input of type "file" is controlled and defined by your browser, so there is nothing you can do from the Shiny side to modify the appearance, but you can hide it.
The file input will react also to the Label, so you can modify the appearance of the label as much as you want.
The first step is to create your own version of the fileinput
function. This new function will hide the tags$input
using CSS and will customize the Label and optionally remove the progress bar.
Below is the code with two file inputs as a button with custom text and icon, also with and without the progress bar.
library(shiny)
# based on the Shiny fileInput function
fileInput2 <- function(inputId, label = NULL, labelIcon = NULL, multiple = FALSE,
accept = NULL, width = NULL, progress = TRUE, ...) {
# add class fileinput_2 defined in UI to hide the inputTag
inputTag <- tags$input(id = inputId, name = inputId, type = "file",
class = "fileinput_2")
if (multiple)
inputTag$attribs$multiple <- "multiple"
if (length(accept) > 0)
inputTag$attribs$accept <- paste(accept, collapse = ",")
div(..., style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
inputTag,
# label customized with an action button
tags$label(`for` = inputId, div(icon(labelIcon), label,
class = "btn btn-default action-button")),
# optionally display a progress bar
if(progress)
tags$div(id = paste(inputId, "_progress", sep = ""),
class = "progress shiny-file-input-progress",
tags$div(class = "progress-bar")
)
)
}
ui <- fluidPage(
# define class fileinput_2 to hide inputTag in fileInput2
tags$head(tags$style(HTML(
".fileinput_2 {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}"
))),
sidebarLayout(
sidebarPanel(
h3("Without progress bar"),
fileInput2("file1", "Load File 1", labelIcon = "folder-open-o",
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv"), progress = FALSE),
h3("With progress bar"),
fileInput2("file2", "Load File 2", labelIcon = "file-code-o",
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv"), progress = TRUE)
),
mainPanel(
verbatimTextOutput("content1"),
verbatimTextOutput("content2")
)
)
)
server <- function(input, output) {
output$content1 <- renderPrint({
inFile <- input$file1
if (is.null(inFile))
return(NULL)
paste("File name 1:", inFile$name)
})
output$content2 <- renderPrint({
inFile <- input$file2
if (is.null(inFile))
return(NULL)
paste("File name 2:", inFile$name)
})
}
shinyApp(ui, server)
