如果未选中复选框,则将数字输入更改为 0

Changing Numeric Inputs to 0 if Check Box is Unchecked

我想知道如果未单击复选框,是否可以通过 updateNumericInput 将数字输入的值设置为等于 0。下面是我的代码是如何设置的,以生成复选框和数字输入。由于应用程序的性质,我不得不使用循环来创建动态数量的复选框和输入,因此我非常感谢在保持功能的同时将两者联系起来的任何帮助。

服务器文件:

  shinyServer(function(input, output, session) {

  output$inputs1 <- renderUI({
    numSliders <- input$sources
    lapply(1:numSliders, function(i) {
      numericInput(
        inputId = paste0('slider1', i),
        label = df[i,2],
        value = df[i,3]*(input$budget)/100)
    })
  })

  output$checks1 <- renderUI({
    numSliders <- input$sources
    lapply(1:numSliders, function(i) {
      checkboxInput(
        inputId = paste0('check1', i),
        label = df[i,2],
        value = TRUE
        )
    })
  })
}

UI:

  shinyUI(fluidPage(fluidRow(
    sidebarLayout(
      sidebarPanel(
        column(5,numericInput("budget", "Budget", value = 0),
          uiOutput("checks1")),
        column(5,uiOutput("inputs1"))),
      mainPanel()
   )
  )
 )
)

如果有任何解决方法,请告诉我。

提前致谢!

由于您只能生成有限数量的小部件,为每个 checkboxInput 创建一个 observer 的最简单方法是创建一个全局变量,例如 max_widgets,它给出一个小部件的上限。然后,您将控制多个小部件的 numericInput 的最大值限制为 max_widgets(因此 input$sources),并要求在 renderUI 秒内

req(numSliders > 0 & numSliders <= max_widgets)

(我会使用 validateneed 来通知用户小部件的数量必须是非负数并且绑定到 max_widgets 但在我的闪亮版本中有一个错误,validate 没有按预期工作。)

然后您在服务器端为每个 checkboxInput 创建观察者:

 lapply(1:max_widgets, function(i) { 
        observeEvent(input[[paste0('check', i)]], {
          print(paste0("update of numeric", i))
            updateNumericInput(session, inputId = paste0('numeric', i),
                               value = 0)
        })
    })

请注意,这将为所有可能的复选框创建观察者(复选框甚至可能不存在 - 闪亮不会抱怨:))

这可能并不完美,但如前所述,每个复选框只有一个观察者。

如果你通过以下方式动态生成观察者(没有全局变量max_widgets

observe({
    lapply(1:input$sources, function(i) {
        observeEvent(input[[paste0('check', i)]], {
          print(paste0("numeric", i, " = ", input[[paste0('numeric', i)]]))
            updateNumericInput(session, inputId = paste0('numeric', i),
                               value = 0)
        })
    })

它也可以工作,但每次您生成新的小部件时,您也会为其创建一个观察器。所以你可能会为每个 checkboxInput 获得多个观察者! 如果您的应用程序很小,那么这无关紧要,但通常它可能会导致错误。您可以轻松处理它,但它会使代码稍微复杂一些 - 有一个 涉及到这个问题。





完整示例:

library(shiny)
rm(list = ls())

max_widgets <- 15

server <- shinyServer(function(input, output, session) {

  output$inputs1 <- renderUI({

    numSliders <- input$sources
    # My shiny version has a bug and can't use validate(need(...)) because
    # it doesn't work as suppossed 
    req(numSliders > 0 & numSliders <= max_widgets)

    lapply(1:numSliders, function(i) {
      numericInput(
        inputId = paste0('numeric', i),
        # label = df[i,2],
        paste0("Input ", i),
        # value = df[i,3] * (input$budget) / 100)
        value = i * (input$budget) / 100)
    })

  })

  output$checks1 <- renderUI({

    numSliders <- input$sources
    req(numSliders > 0 & numSliders <= max_widgets)

    lapply(1:numSliders, function(i) {
      list(
        checkboxInput(
          inputId = paste0('check', i),
          # label = df[i,2],
          label = paste0("Checkbox ", i),
          value = TRUE
         ),
         br()
      )
    })

  })

   lapply(1:max_widgets, function(i) { 
        observeEvent(input[[paste0('check', i)]], {
          print(paste0("update of numeric", i))
            updateNumericInput(session, inputId = paste0('numeric', i),
                               value = 0)
        })
    })

})

ui <- shinyUI(fluidPage(fluidRow(
  sidebarLayout(
    sidebarPanel(
      column(5,
        numericInput("budget", "Budget", value = 0),
        hr(),
        br(),
        uiOutput("checks1")
      ),
      column(5,
        numericInput("sources", "Sources", value = 0, min = 0, max = max_widgets),
        hr(),
        uiOutput("inputs1")
      )
    ),
    mainPanel()
  )
)))
shinyApp(ui, server)