Home > OS >  using observeEvent for numericInput in shiny app
using observeEvent for numericInput in shiny app

Time:07-21

I have a simple shiny app which I would like to show a warning if user input is bigger than a threshold.

library(shiny)
library(shinyalert)

ui <- fluidPage(
  numericInput("obs", "Observations:", 1),
  verbatimTextOutput("value")
)
server <- function(input, output) {
  observeEvent(input$obs,{
    if(!is.na(input$obs) && input$obs >10){
      shinyalert("warning!", "input too big", type = "warning")
    }
  })
  output$value <- renderText({ input$obs })
}
shinyApp(ui, server)

if user is not quick enough to provide input, let say for the input$obs = 110 we have 1 second delay between putting the second and third value the popups warning will appear ! How should I fix this ?

CodePudding user response:

Use shinyCatch from spsComps to make your life easier

library(shiny)
library(spsComps)
ui <- fluidPage(
    numericInput("obs", "Observations:", 1),
    verbatimTextOutput("value")
)
server <- function(input, output) {
    output$value <- renderText({ 
        shinyCatch({
            if(!is.na(input$obs) && input$obs >10) warning("input too big")
        }, blocking_level = "warning", prefix = "")
        
        input$obs 
    })
}
shinyApp(ui, server)

when blocking_level = "warning" is specified shinyCatch blocks following code in the renderText expression. So when your number is larger than 10, the new input$obs will not be rendered.

Here's what users see

enter image description here

Here's what developers see in the console enter image description here

CodePudding user response:

You can use showNotification() from shiny itself:

library(shiny)

ui <- fluidPage(
  numericInput("obs", "Observations:", 1),
  verbatimTextOutput("value")
)
server <- function(input, output) {
  observeEvent(input$obs,{
    if(!is.na(input$obs) && input$obs >10){
      showNotification(
        ui = tags$h4("Input Too Big!"), 
        type = "warning"
      )
    }
  })
  output$value <- renderText({ input$obs })
}
shinyApp(ui, server)

Or {shinytoastr}:

library(shiny)
library(shinytoastr)

ui <- fluidPage(
  shinytoastr::useToastr(), 
  
  numericInput("obs", "Observations:", 1),
  verbatimTextOutput("value")
)
server <- function(input, output) {
  observeEvent(input$obs,{
    if(!is.na(input$obs) && input$obs >10){
      shinytoastr::toastr_warning(
        message = "Decrease it.", 
        title = "Input too big!"
      )
    }
  })
  output$value <- renderText({ input$obs })
}
shinyApp(ui, server)

Or {spsComps} as @lz100 mentioned. The choice is yours.

  • Related