Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I update a shiny fileInput object?

Tags:

r

shiny

I want to create an input file dialog. This is straightforward using the fileInput function.

shinyUI(pageWithSidebar(   headerPanel(""),   sidebarPanel(     fileInput("file", "Select a file")     ),   mainPanel() )) 

enter image description here

After uploading it looks like this: enter image description here

Now, I want to reset the inputFile element to the state it had before uploading. As there is no such function like updateFileInput, me being a JS/HTML rookie, I am not able to figure out how I could achieve that. The code output from fileInput("file", "Select a file") is the following.

<label>Select a file</label> <input id="file" type="file" accept="text/plain"/> <div id="file_progress" class="progress progress-striped active shiny-file-input-progress">   <div class="bar"></div>   <label></label> </div>  

Any ideas?

PS. I do not want to use a reactive renderUI here to re-render the file input element. I'd rather want to go the 'update way' (if there is such a thing) ...

like image 755
Mark Heckmann Avatar asked Jun 27 '13 19:06

Mark Heckmann


People also ask

How do I upload a shiny file in R?

The UI needed to support file uploads is simple: just add fileInput() to your UI. Like most other UI components, there are only two required arguments: id and label . The width , buttonLabel and placeholder arguments allow you to tweak the appearance in other ways.


1 Answers

As @Julien Navarre pointed out, this boils down to modifying some HTML/CSS. Julien showed how to do that from the client side. What remains to be shown is how to do that from the server side. I.e. the server will invoke a function on the client side that will set back the input handler. You can find a blog post on passing data between server and client using shiny here.

On the server side the crucial function is session$sendCustomMessage which will call a the handler function resetFileInputHandler on the client side. The id of the file input object is passed to the handler.

server.R

shinyServer(function(input, output, session) {    observe({     input$btn     session$sendCustomMessage(type = "resetFileInputHandler", "file1")    })  }) 

Now, on the client side we need to register a handler function that will be called by the server and perform the necessary changes as outlined by Julien.

ui.R

shinyUI(bootstrapPage(    fileInput('file1', 'Choose File'),   actionButton("btn", "Trigger server to reset file input"),    tags$script('     Shiny.addCustomMessageHandler("resetFileInputHandler", function(x) {               var id = "#" + x + "_progress";      # name of progress bar is file1_progress         var idBar = id + " .bar";           $(id).css("visibility", "hidden");   # change visibility         $(idBar).css("width", "0%");         # reset bar to 0%     });   ') )) 

Pressing the button will now cause the server to invoke the resetFileInputHandler on the client side (of course the button is just for demo puposes).

You can find the above code here or run it like this

library(shiny) runGist("8314905") 

Caution

This solution leaves on aspect untouched:The file name shown to the right for the shiny object

<input id="file1" type="file" class="shiny-bound-input"> 

is not altered. I guess that would mean digging deeper into it. Suggestions are welcome.

like image 179
Mark Heckmann Avatar answered Sep 22 '22 19:09

Mark Heckmann