Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
442 views
in Technique[技术] by (71.8m points)

r - how can I update a shiny fileInput object?

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) ...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...