【问题标题】:'Reset inputs' button in shiny app闪亮应用程序中的“重置输入”按钮
【发布时间】:2014-08-07 14:15:06
【问题描述】:

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

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

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

))

我想知道是否还有一个功能可以将所有内容恢复为默认值?这在有多个输入的情况下会很有用。

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

【问题讨论】:

    标签: r shiny


    【解决方案1】:

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

    【讨论】:

    • 非常感谢!我已经在我的原始应用程序上尝试了代码(使用 11 个输入而不是 2 个输入),它工作得非常好,而且代码中没有两次输入是一件好事。顺便说一句:我能在某个地方找到对 html 标签有很好帮助的地方吗?到目前为止,我还不知道“id”及其用途。
    • @Matthew Plourde, @Insa 我不认为 div 和 id 在这里真的很重要。我将div(id=letters[(times %% length(letters)) + 1], 替换为list 并没有改变。
    • 这是我发现自己又回来的答案之一,希望我能投票,但在遥远的过去一定是这样做的。比编写观察者并且必须重写所有内容要简单得多。
    • 得说,这是一个巨大的节省时间......如果我在浪费时间之前看到它!
    • 在我什至不知道我要搜索什么之前偶然发现了这个解决方案(updateTextInput?)。很棒的解决方案。
    【解决方案2】:

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

    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 部分重置为其原始值。以下是如何将原始代码调整为您想要的行为,这种方式可以扩展到任意数量的输入,而无需添加任何代码。我所要做的就是在 UI 中添加对 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")
        })
      }
    
    ))
    

    【讨论】:

    • 我正在寻找一些关于过滤数据和生成交叉表和绘图的帮助。我真的很感激任何帮助,让我知道如何让它工作。我已经发布了我的问题,希望您能够提出一些解决方案。谢谢!!我的帖子的链接是stackoverflow.com/questions/41187194/…
    • 谢谢Dean,您认为可以直接在闪亮或闪亮的仪表盘包中添加您的功能吗?
    • @DimitriPetrenko 你的意思是把重置功能变成闪亮的吗?我认为这不会发生。如果他们愿意,您可以向 rstudio 询问。但是shinyjs 还有很多其他类似有用的功能,所以我认为将它们打包在一起是有意义的
    • @DeanAttali 如果您使用的是flexdashboard,您在shinyjs::reset() 中引用了什么参数来表明您要重置侧边栏面板?问题是在flexdashboard 中,您没有明确地向侧边栏面板提供id 名称。
    • 没关系 - 我知道您可以参考输入本身,这也同样有效。
    【解决方案3】:

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

    它使用:

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

    session$sendInputMessage 更新通用输入的值。 updateXyzInput 函数在底层调用它,如 session$sendInputMessage(inputId, list(value = x, ...)

    每个 Shiny 输入都使用value 作为其输入消息,并且几乎所有输入都将按原样更新其输入值。我发现只有两个输入需要特殊的大小写 - checkboxGroupInput 在未检查任何内容时不发送 NULLdateRangeInput 将其 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)
    

    【讨论】:

      【解决方案4】:

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

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

      如果担心的话,本文提供的解决方案不需要额外的软件包。

      【讨论】:

        猜你喜欢
        • 2019-02-02
        • 2017-11-30
        • 2020-08-12
        • 2019-08-09
        • 2019-06-18
        • 2017-11-15
        • 2020-05-10
        • 2022-01-20
        • 2014-10-04
        相关资源
        最近更新 更多