闪亮应用中的“重置输入”按钮

时间:2014-06-17 14:07:09

标签: r shiny

我想在我的闪亮应用中实现“重置输入”按钮。

这是一个只有两个输入的例子,我正在使用更新函数将值设置回默认值:

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

))

我想知道的是,是否还有一个功能可以将所有内容设置为默认值?在多个输入的情况下,这将非常有用。

此外,我不确定我是否使用了观察功能来检测动作按钮何时被击中是处理动作按钮的“正确方法”?

4 个答案:

答案 0 :(得分:30)

shiny中没有这样的功能,但是,这里有一种方法可以实现这一点,而无需基本上定义输入两次。诀窍是使用uiOutput并将要重置的输入包装在div中,每次按下重置按钮时,其id将更改为新的。

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

  }
))

答案 1 :(得分:27)

首先,您对观察者的使用是正确的,但还有另一种方法更好一些。而不是

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

您可以将其更改为

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

另请注意,您不需要从renderText函数显式“返回”,将自动使用最后一个语句。

关于主要问题:Matthew的解决方案很棒,但是也有一种方法可以实现您想要的而无需将所有UI移动到服务器中。我认为最好将UI保存在UI文件中,因为结构和逻辑的分离通常是个好主意。

完全免责声明:我的解决方案涉及使用我编写的包。我的包shinyjs具有reset功能,允许您将输入或HTML部分重置为其原始值。以下是如何将原始代码调整为所需行为,以便可以扩展到任意数量的输入,而无需添加任何代码。我所要做的就是在用户界面中添加对useShinyjs()的调用,在表单中添加“id”属性,然后在表单上调用reset(id)

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

))

答案 2 :(得分:1)

这是另一个适用于静态或动态输入的选项,并且不涉及完全重新渲染输入。

它使用:

reactiveValuesToList获取所有初始输入值,以及(可选)之后初始化的任何动态输入值。

session$sendInputMessage更新通用输入的值。 updateXyzInput函数会像session$sendInputMessage(inputId, list(value = x, ...)一样调用它。

每个Shiny输入都使用value作为输入消息,几乎所有输入都会按原样更新输入值。我发现只有两个输入需要特殊的大小写 - checkboxGroupInput在未选中任何内容时不发送NULL,并dateRangeInput将其c(start, end)转换为list(start = start, end = end) }。

盲目地重置所有输入可能不是一个好主意(即使标签会被重置),但这可以很容易地适应重置过滤的一组输入。

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)

答案 3 :(得分:1)

您还可以通过将NULL分配给您的被动值对象来创建重置按钮。

请参阅使用操作按钮http://shiny.rstudio.com/articles/action-buttons.html上的这篇RStudio Shiny文章。具体来说,请阅读标题为模式4 - 重置按钮模式5 - 重置选项卡的章节。示例(包括代码)在文章中提供。

如果这是一个问题,那么该文章提供的解决方案不需要额外的包。