Botón ‘Restablecer entradas’ en la shiny aplicación

Me gustaría implementar un botón ‘Restablecer entradas’ en mi shiny aplicación.

Aquí hay un ejemplo con solo dos entradas donde estoy usando las funciones de actualización para establecer los valores de nuevo a los valores predeterminados:

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") }) } )) 

Lo que me gustaría saber es si también hay una función que restablece todo a la configuración predeterminada. Eso sería útil en caso de múltiples entradas.

Además, no estoy seguro si mi uso de la función de observación para detectar cuándo se presionó el botón de acción es la “forma correcta” de manejar los botones de acción.

No hay tal función en shiny , sin embargo, aquí hay una manera de lograr esto sin tener que definir esencialmente sus entradas dos veces. El truco es usar uiOutput y envolver las entradas que desea restablecer en un div cuyo ID cambia a algo nuevo cada vez que se presiona el botón de reinicio.

 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")) }) } )) 

En primer lugar, su uso del observador es correcto, pero hay otra manera que es ligeramente mejor. En lugar de

 observe({ input$reset_input updateNumericInput(session, "mynumber", value = 20) updateTextInput(session, "mytext", value = "test") }) 

Puedes cambiarlo a

 observeEvent(input$reset_input, { updateNumericInput(session, "mynumber", value = 20) updateTextInput(session, "mytext", value = "test") }) 

También tenga en cuenta que no necesita “devolver” explícitamente una función renderText, la última statement se utilizará automáticamente.


En cuanto a la pregunta principal: la solución de Matthew es excelente, pero también hay una forma de lograr lo que quiere sin tener que mover toda su UI al servidor. Creo que es mejor mantener su UI en el archivo UI solo porque la separación de estructura y lógica es generalmente una buena idea.

Descargo de responsabilidad completo: mi solución implica el uso de un paquete que escribí. Mi paquete shinyjs tiene una función de reset que le permite restablecer una entrada o una sección HTML a su valor original. A continuación se explica cómo ajustar el código original al comportamiento deseado de una forma que se escalará a cualquier cantidad de entradas sin tener que agregar ningún código. Todo lo que tuve que hacer es agregar una llamada para useShinyjs() en la interfaz de usuario, agregar un atributo “id” al formulario y reset(id) llamada reset(id) en el formulario.

 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") }) } )) 

Aquí hay otra opción que funciona para entradas estáticas o dinámicas, y no implica volver a procesar las entradas por completo.

Usa:

reactiveValuesToList para obtener todos los valores de entrada iniciales y (opcionalmente) cualquier valor de entrada dinámica que se inicialice después.

session$sendInputMessage para actualizar valores para entradas genéricas. Las funciones updateXyzInput llaman a esto bajo el capó como la session$sendInputMessage(inputId, list(value = x, ...) .

Cada entrada shiny utiliza el value de su mensaje de entrada, y casi todo se actualizará con su valor de entrada tal como está. Solo dos entradas que he encontrado necesitan una envoltura especial – checkboxGroupInput para no enviar NULL cuando nada está marcado, y dateRangeInput para convertir su c(start, end) en una list(start = start, end = end) .

Puede que no sea una buena idea restablecer ciegamente TODAS las entradas (incluso las tabs se restablecerán), pero esto se puede adaptar fácilmente para reiniciar un conjunto filtrado de entradas.

 library(shiny) ui <- pageWithSidebar( headerPanel("'Reset inputs' button example"), sidebarPanel( numericInput("mynumber", "Enter a number", 20), textInput("mytext", "Enter text", "test"), textAreaInput("mytextarea", "Enter text", "test"), passwordInput("mypassword", "Enter a password", "password"), checkboxInput("mycheckbox", "Check"), checkboxGroupInput("mycheckboxgroup", "Choose a number", choices = c(1, 2, 3)), radioButtons("myradio", "Select a number", c(1, 2, 3)), sliderInput("myslider", "Select a number", 1, 5, c(1,2)), uiOutput("myselUI"), uiOutput("mydateUI"), tags$hr(), actionButton("reset_input", "Reset inputs") ), mainPanel( h4("Summary"), verbatimTextOutput("summary") ) ) server <- function(input, output, session) { initialInputs <- isolate(reactiveValuesToList(input)) observe({ # OPTIONAL - save initial values of dynamic inputs inputValues <- reactiveValuesToList(input) initialInputs <<- utils::modifyList(inputValues, initialInputs) }) observeEvent(input$reset_input, { for (id in names(initialInputs)) { value <- initialInputs[[id]] # For empty checkboxGroupInputs if (is.null(value)) value <- "" session$sendInputMessage(id, list(value = value)) } }) output$myselUI <- renderUI({ selectInput("mysel", "Select a number", c(1, 2, 3)) }) output$mydateUI <- renderUI({ dateInput("mydate", "Enter a date") }) output$summary <- renderText({ return(paste(input$mytext, input$mynumber)) }) } shinyApp(ui, server) 

También puede crear un botón de reinicio asignando NULL a su objeto de valores reactivos.

Vea este artículo de RStudio Shiny sobre el uso de botones de acción : http://shiny.rstudio.com/articles/action-buttons.html . Específicamente, lea las secciones tituladas Patrón 4 – Botones de reinicio y Patrón 5 – Reinicio en el cambio de pestaña . Los ejemplos (incluido el código) se proporcionan en el artículo.

El artículo proporciona soluciones que no requieren paquetes adicionales si eso es una preocupación.