rshinyshinydashboardshinydashboardplus

Show only one notification in Shiny


I would like to control the phone number by showing a notification :

I used the function showNotification from shiny with closeButton = FALSE and duration = NULL.

When the user type a wrong number, the notification popped up but when he type a long number the the notification also popped up but the previous one does not disappear

I would like to show only one notification (wrong number or long number) but not the both at the same time. How can we do that ? Here's my apps :

library(shiny)
library(shinydashboard)
library(shinydashboardPlus)

############# UI ############
body <- dashboardBody(
  tabItems(
    tabItem(tabName = "tab1",
            fluidRow(
              tags$h1('my title'),
              
              textInput("phone_number", "enter your phone number", value = ""),
              
              actionButton("button", "go")
              
            )
    )
  )
  
  
)

ui <- dashboardPage(
  
  title = "Example",
  options = list(sidebarExpandOnHover = TRUE),
  header = dashboardHeader(disable = FALSE),
  sidebar = dashboardSidebar(
    minified = TRUE, collapsed = TRUE,
    sidebarMenu(id="menu",
                menuItem("first tab", tabName =  "mytab", icon = icon("fas fa-acorn"),
                         menuSubItem('menu1',
                                     tabName = 'tab1',
                                     icon = icon('fas fa-hand-point-right'))
                )
    )
  ),
  body
)


############# SERVER ############
server <- function(input, output) {
  
  
  
  observeEvent(
    input$button,
    {
      if(is.na(as.numeric(input$phone_number))) {
        showNotification(type = "error",
                         duration = NULL,
                         closeButton = FALSE,
                         "wrong number")
        
      } else if(nchar(input$phone_number)<10) {
        showNotification(type = "error",
                         duration = NULL,
                         closeButton = FALSE,
                         "too long (10 digits required)")
        
      }
    }
  )
  
  
}

############# RUN THE APP ############
shinyApp(ui = ui, server = server)

Some help would be appreciated


Solution

  • I would not use a notification here, because they will always be displayed for a fixed time duration and at a different position of the window, which might confuse the user. I would just render the message in using a textOutput:

    library(shiny)
    library(shinyjs)
    
    ui <- fluidPage(
      useShinyjs(),
      textInput("phone_number", "phone number"),
      textOutput("phone_notification")
    )
    
    server <- function(input, output, session) {
      output$phone_notification <- renderText({
        if(input$phone_number == "") {
          "" # empty is ok
        }
        else if(is.na(as.numeric(input$phone_number))) {
          "wrong number"
        } else if (nchar(input$phone_number) > 10) {
          "too long"
        } else {
          "" # correct number
        }
      })
    }
    
    shinyApp(ui, server)
    

    enter image description here

    You can also style the text e.g. to make it red:

    ui <- fluidPage(
      useShinyjs(),
      textInput("phone_number", "phone number"),
      tagAppendAttributes(
        textOutput("phone_notification"),
        style = "color:red"
      )
    )