Mehdi Nellen
Mehdi Nellen

Reputation: 8964

Conditional fileInput uploader to count number of files in Shiny

I have the following shiny app

require(shiny)

ui <- fluidPage(  
  numericInput("num", "num:", 10, min = 1, max = 100),
  fileInput(inputId = "upl", multiple = T, label = "upl")
)

server <- function(input, output) { 

}

shinyApp(ui, server)

I would like the fileInput uploader to only upload the files if its the amount of files specified in the numericInput. Otherwise it should give a message the amount of files is wrong.

I tried to use shinyjs for this

//remove existing listener
document.getElementById('upl').outerHTML = document.getElementById('upl').outerHTML;
document.getElementById('upl').addEventListener('change', function() { 
  if(document.getElementById('upl').files.length == document.getElementById('num').value) {
    // something that uploads the files
    // I tried to copy the function from the already existing listener, but its anonymous and has no reference so its impossible to copy
  } else {
     alert('wrong number of files');
  } 
})

I haven't figured out a way to stop or initiate the upload based on the conditional, because the input element already has an event listener on it with an anonymous function which I am unable to copy.

There might be an easier way which I'm unaware of, any idea how to build a conditional uploader in shiny?

Upvotes: 1

Views: 376

Answers (1)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84529

This seems to work:

library(shiny)
library(shinyjs)

js <- "
$(document).ready(function(){
document.getElementById('upl').addEventListener('change', function() { 
  if(document.getElementById('upl').files.length == document.getElementById('num').value) {
    return true;
  } else {
    alert('wrong number of files');
    this.value = '';
    return false;
  } 
})
})"

ui <- fluidPage(
  useShinyjs(),
  tags$head(tags$script(HTML(js))),
  numericInput("num", "num:", 2, min = 1, max = 100),
  fileInput(inputId = "upl", multiple = T, label = "upl")
)

server <- function(input, output) { }

shinyApp(ui, server)

Upvotes: 1

Related Questions