tutorial - the django project
Botón ''Restablecer entradas'' en la brillante aplicación (3)
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 brillante 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 pestañas 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)
Me gustaría implementar un botón ''Restablecer entradas'' en mi brillante 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 declaración 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")
})
}
))