I would like to implement a 'Reset inputs' button in my shiny app.
Here is an example with just two inputs where I'm using the update functions to set the values back to the default values:
library(shiny) runApp(list( ui = pageWithSidebar( headerPanel("'Reset inputs' button example"), sidebarPanel( numericInput("mynumber", "Enter a number", 20), textInput("mytext", "Enter a text", "test"), tags$hr(), actionButton("reset_input", "Reset inputs") ), mainPanel( h4("Summary"), verbatimTextOutput("summary") ) ), server = function(input, output, session) { output$summary <- renderText({ return(paste(input$mytext, input$mynumber)) }) observe({ input$reset_input updateNumericInput(session, "mynumber", value = 20) updateTextInput(session, "mytext", value = "test") }) } ))
What I would like to know is if there is also a function that sets back everything to default? That would be useful in case of multiple inputs.
Additionally, I'm not sure if my use of the observe function in order to detect when the action button was hit is the 'proper way' of handling the action buttons?
The shiny window displays a greyed out/cancelled app. To get the new instance of the app to show, you have to click the refresh button.
Action buttons and action links are meant to be used with one of observeEvent() or eventReactive() . You can extend the effects of an action button with reactiveValues() . Use observeEvent() to trigger a block of code with an action button. Use eventReactive() to update derived/calculated output with an action button.
Shiny uses the function fluidPage to create a display that automatically adjusts to the dimensions of your user's browser window. You lay out the user interface of your app by placing elements in the fluidPage function.
shinyApp. Finally, we use the shinyApp function to create a Shiny app object from the UI/server pair that we defined above. We save all of this code, the ui object, the server function, and the call to the shinyApp function, in an R script called app.
There isn't such a function in shiny
, however, here's a way to accomplish this without having to essentially define your inputs twice. The trick is to use uiOutput
and wrap the inputs you want to reset in a div
whose id changes to something new each time the reset button is pressed.
library(shiny) runApp(list( ui = pageWithSidebar( headerPanel("'Reset inputs' button example"), sidebarPanel( uiOutput('resetable_input'), tags$hr(), actionButton("reset_input", "Reset inputs") ), mainPanel( h4("Summary"), verbatimTextOutput("summary") ) ), server = function(input, output, session) { output$summary <- renderText({ return(paste(input$mytext, input$mynumber)) }) output$resetable_input <- renderUI({ times <- input$reset_input div(id=letters[(times %% length(letters)) + 1], numericInput("mynumber", "Enter a number", 20), textInput("mytext", "Enter a text", "test")) }) } ))
First of all, your use of the observer is correct, but there is another way that's slightly nicer. Instead of
observe({ input$reset_input updateNumericInput(session, "mynumber", value = 20) updateTextInput(session, "mytext", value = "test") })
You can change it to
observeEvent(input$reset_input, { updateNumericInput(session, "mynumber", value = 20) updateTextInput(session, "mytext", value = "test") })
Also note that you don't need to explicitly "return" from a renderText function, the last statement will automatically be used.
Regarding the main question: Matthew's solution is great, but there's also a way to achieve what you want without having to move all your UI into the server. I think it's better practice to keep your UI in the UI file just because separation of structure and logic is generally a good idea.
Full disclaimer: my solution involves using a package that I wrote. My package shinyjs has a reset
function that allows you to reset an input or an HTML section back to its original value. Here is how to tweak your original code to your desired behaviour in a way that will scale to any number of inputs without having to add any code. All I had to do is add a call to useShinyjs()
in the UI, add an "id" attribute to the form, and call reset(id)
on the form.
library(shiny) runApp(list( ui = pageWithSidebar( headerPanel("'Reset inputs' button example"), sidebarPanel( shinyjs::useShinyjs(), id = "side-panel", numericInput("mynumber", "Enter a number", 20), textInput("mytext", "Enter a text", "test"), tags$hr(), actionButton("reset_input", "Reset inputs") ), mainPanel( h4("Summary"), verbatimTextOutput("summary") ) ), server = function(input, output, session) { output$summary <- renderText({ return(paste(input$mytext, input$mynumber)) }) observeEvent(input$reset_input, { shinyjs::reset("side-panel") }) } ))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With