Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'Reset inputs' button in shiny app

Tags:

r

shiny

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?

like image 965
Insa Avatar asked Jun 17 '14 14:06

Insa


People also ask

How do you refresh a shiny app?

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.

How do you use the shiny action 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.

What is UI in shiny?

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.

Which function is used to create shiny app?

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.


2 Answers

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"))     })    } )) 
like image 76
Matthew Plourde Avatar answered Sep 28 '22 12:09

Matthew Plourde


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")     })   }  )) 
like image 32
DeanAttali Avatar answered Sep 28 '22 12:09

DeanAttali