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

Ins*_*nsa 33 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")
    })
  }

))
Run Code Online (Sandbox Code Playgroud)

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

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

Mat*_*rde 32

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

  }
))
Run Code Online (Sandbox Code Playgroud)

  • @Matthew Plourde,@ Insa我认为div和id在这里并不重要。我用“ list”替换了“ div(id = letters [(times %% length(letters))+ 1]]”,但它什么都没有改变。 (3认同)

Dea*_*ali 28

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

observe({
  input$reset_input
  updateNumericInput(session, "mynumber", value = 20)
  updateTextInput(session, "mytext", value = "test")
})
Run Code Online (Sandbox Code Playgroud)

你可以把它改成

observeEvent(input$reset_input, {
  updateNumericInput(session, "mynumber", value = 20)
  updateTextInput(session, "mytext", value = "test")
})
Run Code Online (Sandbox Code Playgroud)

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


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

完全免责声明:我的解决方案涉及使用我编写的包.我的包shinyjs有一个reset函数,允许您将输入或HTML部分重置回其原始值.以下是如何将原始代码调整为所需行为,以便可以扩展到任意数量的输入,而无需添加任何代码.我所要做的就是useShinyjs()在UI中添加一个调用,在表单中添加一个"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")
    })
  }

))
Run Code Online (Sandbox Code Playgroud)

  • @DimitriPetrenko你的意思是将重置功能移动到闪亮的?我认为这不会发生.如果他们愿意的话,你可以问rstudio.但是shinyjs还有许多其他类似的功能,所以我认为将它们保持在一起是有意义的 (2认同)

gre*_*g L 9

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

它用:

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

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

每个 Shiny 输入都用于value其输入消息,并且几乎所有输入都会按原样更新其输入值。我发现只有两个输入需要特殊的大小写 -当没有检查任何内容时checkboxGroupInput不发送,并将其转换为.NULLdateRangeInputc(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)
Run Code Online (Sandbox Code Playgroud)