首页 文章

闪亮的应用程序中的'Reset inputs'按钮

提问于
浏览
31

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

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

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

))

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

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

4 回答

  • 29

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

    请参阅 Using Action Buttons 上的这篇RStudio Shiny文章:http://shiny.rstudio.com/articles/action-buttons.html . 具体来说,请阅读 Headers 为模式4 - 重置按钮和模式5 - 重置选项卡更改的部分 . 文章中提供了示例(包括代码) .

    如果这是一个问题,本文提供的解决方案不需要额外的包 .

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

    首先,你对观察者的使用是正确的,但还有另一种方法更好一些 . 代替

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

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

    它用:

    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)
    

相关问题