Skip to content

Ηow can I get the filename of a file uploaded with a shiny fileInput?

I have the shiny app below in which the user lands on the Upload data panel. I want the user not to be able to move to any of the other 2 tabpanels if he has not uploaded both files that are needed in the Upload data tab. The thing here is that I want both tabs to be activated only if the csv names are specific. For example the csv imported in first or second fileInput() should be named csvone and the csv imported in the first or second fileInput() should be named csvtwo. But both files should be uploaded regardless of which will be 1st.

library(shiny)
library(shinyjs)

jscode <- "
shinyjs.disableTab = function(name) {
  var tab = $('.nav li a[data-value=' + name + ']');
  tab.bind('click.tab', function(e) {
    e.preventDefault();
    return false;
  });
  tab.addClass('disabled');
}

shinyjs.enableTab = function(name) {
  var tab = $('.nav li a[data-value=' + name + ']');
  tab.unbind('click.tab');
  tab.removeClass('disabled');
}
"

css <- "
.nav li a.disabled {
  background-color: #aaa !important;
  color: #333 !important;
  cursor: not-allowed !important;
  border-color: #aaa !important;
}"

#ui.r
ui <- fluidPage(
  useShinyjs(),
  extendShinyjs(text = jscode, functions = c("disableTab","enableTab")),
  inlineCSS(css),
  # App title ----
  titlePanel("Tabsets"),
  
  # Sidebar layout with input and output definitions ----
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(
    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      tabsetPanel( id="tabset",
                   tabPanel("Upload data", value="tab0",
                            fileInput("file1", "Choose CSV File",
                                      multiple = TRUE,
                                      accept = c("text/csv",
                                                 "text/comma-separated-values,text/plain",
                                                 ".csv")),
                            fileInput("file2", "Choose CSV File",
                                      multiple = TRUE,
                                      accept = c("text/csv",
                                                 "text/comma-separated-values,text/plain",
                                                 ".csv"))),
                   tabPanel("Resource Allocation", value="tab1"),
                   tabPanel("Time Series", value="tab2")
      )
    )
  )
)
#server.r

server = function(input, output) {
  print("test")
  js$disableTab("tab1")
  js$disableTab("tab2")
 
 observe({
  req(input$file1, input$file2)
  js$enableTab("tab1")
  js$enableTab("tab2")
})
}

shinyApp(ui, server)

Answer

just wrap the enable commands in an if/else statement like so

BTW: what you are (should be) asking essentially is “how can I get the filename of a file uploaded with a shiny fileInput?”

library(shiny)
library(shinyjs)

jscode <- "
shinyjs.disableTab = function(name) {
  var tab = $('.nav li a[data-value=' + name + ']');
  tab.bind('click.tab', function(e) {
    e.preventDefault();
    return false;
  });
  tab.addClass('disabled');
}

shinyjs.enableTab = function(name) {
  var tab = $('.nav li a[data-value=' + name + ']');
  tab.unbind('click.tab');
  tab.removeClass('disabled');
}
"

css <- "
.nav li a.disabled {
  background-color: #aaa !important;
  color: #333 !important;
  cursor: not-allowed !important;
  border-color: #aaa !important;
}"

#ui.r
ui <- fluidPage(
  useShinyjs(),
  extendShinyjs(text = jscode, functions = c("disableTab","enableTab")),
  inlineCSS(css),
  # App title ----
  titlePanel("Tabsets"),
  
  # Sidebar layout with input and output definitions ----
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(
    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      tabsetPanel( id="tabset",
                   tabPanel("Upload data", value="tab0",
                            fileInput("file1", "Choose CSV File",
                                      multiple = TRUE,
                                      accept = c("text/csv",
                                                 "text/comma-separated-values,text/plain",
                                                 ".csv")),
                            fileInput("file2", "Choose CSV File",
                                      multiple = TRUE,
                                      accept = c("text/csv",
                                                 "text/comma-separated-values,text/plain",
                                                 ".csv"))),
                   tabPanel("Resource Allocation", value="tab1"),
                   tabPanel("Time Series", value="tab2")
      )
    )
  )
)
#server.r

server = function(input, output) {
  js$disableTab("tab1")
  js$disableTab("tab2")
 
 observe({
  req(input$file1, input$file2)
  if(input$file1$name == "csvone.csv" && input$file2$name == "csvtwo.csv"){
    js$enableTab("tab1")
    js$enableTab("tab2")
  }
})
}

shinyApp(ui, server)