如果删除所有数字,闪亮的 numericInput 字段设置为零

Shiny numericInput field set to zero if all numbers deleted

这里有两个 numericInput 字段,其总计显示在第三个字段中。 如果我突出显示字段 A 中的所有数字并按删除或 space 该字段留空并且总和不再有效,因为并非所有要添加的元素都是数字。

在以下情况下,如何让字段显示“0”:

此外,即使它是数字字段,也允许使用键“e”、“.”和“+”。可以不让他们出现吗?

library("shiny")
library("bslib")
library("shinyWidgets")

ui <- bootstrapPage(
  # https://bootswatch.com/journal/
  theme = bs_theme(version = 5, "font_scale" = 1.0), 
  div(class = "container-fluid",
      
      div(class = "row",
          div(class="col-4", 
              numericInputIcon(
                inputId = "a",
                label = "A",
                value = 10,
                min = 0,
                max = 9000,
                width = "160px",
                icon = list(NULL, per_month)
              ),
          ),
          div(class="col-4", 
              numericInputIcon(
                inputId = "b",
                label = "B",
                value = 255,
                min = 0,
                max = 9000,
                width = "160px",
                icon = list(NULL, per_month)
              ),
          ),
          div(class="col-4", 
              numericInputIcon(
                inputId = "total",
                label = "Total",
                value = 0,
                min = 0,
                max = 9000,
                width = "160px",
                icon = list(NULL, per_month)
              ),
          ),
      )
  )
)

server <- function(input, output, session) {
  observe({
    updateNumericInputIcon(
      session = session,
      inputId = "total",
      value = sum(c(input$a, input$b),na.rm=T)
    )
  })
  
  # This doesn't seem to work
  observe({
    if (!is.numeric(input$a)) {
      updateNumericInput(session, "a", 0)
    }
  })
}

shinyApp(ui = ui, server = server)

您上面的代码使用 updateNumericInput 而不是 updateNumericInputIcon。如果您没有按预期顺序传递命名参数,还请确保提供命名参数:

library("shiny")
library("bslib")
library("shinyWidgets")

ui <- bootstrapPage(
  # https://bootswatch.com/journal/
  theme = bs_theme(version = 5, "font_scale" = 1.0), 
  div(class = "container-fluid",
      
      div(class = "row",
          div(class="col-4", 
              numericInputIcon(
                inputId = "a",
                label = "A",
                value = 10,
                min = 0,
                max = 9000,
                width = "160px",
                icon = list(NULL, per_month)
              ),
          ),
          div(class="col-4", 
              numericInputIcon(
                inputId = "b",
                label = "B",
                value = 255,
                min = 0,
                max = 9000,
                width = "160px",
                icon = list(NULL, per_month)
              ),
          ),
          div(class="col-4", 
              numericInputIcon(
                inputId = "total",
                label = "Total",
                value = 0,
                min = 0,
                max = 9000,
                width = "160px",
                icon = list(NULL, per_month)
              ),
          ),
      )
  )
)

server <- function(input, output, session) {
  observe({
    freezeReactiveValue(input, "total")
    updateNumericInputIcon(
      session = session,
      inputId = "total",
      value = sum(c(input$a, input$b),na.rm=T)
    )
  })
  
  observe({
    if (!is.numeric(input$a)) {
      freezeReactiveValue(input, "a")
      updateNumericInputIcon(session, inputId = "a", value = 0)
    }
  })
}

shinyApp(ui = ui, server = server)

为避免不必要地触发反应或输出,在 Mastering Shiny 中的 . Please see this related chapter 中使用 update* 函数时,您应该几乎总是使用 freezeReactiveValue .

长期 运行 我建议使用库 (shinyvalidate).