Interactive directory input in Shiny app (R) -
i building shiny app requires user select folder on local machine, contains files processed app.
i using solution proposed here. works fine on local machine, not work if app deployed shinyapps server. author of solution confirmed designed work local shiny apps, since makes os shell calls display directory dialog.
i wondering if there different solution directory dialog, work on deployed shiny apps (i deploying shinyapps.io).
edited: notice cannot use fileinput interface 2 reasons:
- the users of app not technical people , not know files inside folder used app.
- the selected folder may contain other folders within needed files reside, such impossible select files @ once, if fileinput interface has
multiple
option enabled.
the folder/files structure not can change, downloaded medical device , therefore thing can expect users specify parent folder , rest should done inside r code.
this working example based on using "webkitdirectory" attribute. @ moment attribute supported chrome, opera , safari (mobile , desktop) should supported in firefox 49 released in september. more here work subdirectories also.
it require using tags keyword in ui.r. have tested uploading 3 csv files each contaning 3 numbers separeted coma. test locally , on shinyapps.io wiht chrome , opera code:
ui.r
library(shiny) library(dt) shinyui(taglist(fluidpage(theme = "bootstrap.css", includescript("./www/text.js"), titlepanel("folder content upload"), fluidrow( column(4, wellpanel( tags$div(class="form-group shiny-input-container", tags$div(tags$label("file input")), tags$div(tags$label("choose folder", class="btn btn-primary", tags$input(id = "filein", webkitdirectory = true, type = "file", style="display: none;", onchange="pressed()"))), tags$label("no folder choosen", id = "nofile"), tags$div(id="filein_progress", class="progress progress-striped active shiny-file-input-progress", tags$div(class="progress-bar") ) ), verbatimtextoutput("results") ) ), column(8, tabsetpanel( tabpanel("files table", datatableoutput("tbl")), tabpanel("files list", datatableoutput("tbl2")) ) ) ) ), html("<script type='text/javascript' src='getfolders.js'></script>") ) )
server.r
library(shiny) library(ggplot2) library(dt) shinyserver(function(input, output, session) { df <- reactive({ infiles <- input$filein df <- data.frame() if (is.null(infiles)) return(null) (i in seq_along(infiles$datapath)) { tmp <- read.csv(infiles$datapath[i], header = false) df <- rbind(df, tmp) } df }) output$tbl <- dt::renderdatatable( df() ) output$tbl2 <- dt::renderdatatable( input$filein ) output$results = renderprint({ input$mydata }) })
text.js
window.pressed = function(){ var = document.getelementbyid('filein'); if(a.value === "") { nofile.innerhtml = "no folder choosen"; } else { nofile.innerhtml = ""; } };
getfolders.js
document.getelementbyid("filein").addeventlistener("change", function(e) { let files = e.target.files; var arr = new array(files.length*2); (let i=0; i<files.length; i++) { //console.log(files[i].webkitrelativepath); //console.log(files[i].name); arr[i] = files[i].webkitrelativepath; arr[i+files.length] = files[i].name; } shiny.oninputchange("mydata", arr); });
let me know if helps.
Comments
Post a Comment