Home > Net >  shinyvalidate -warning message won't appear after inserting UI
shinyvalidate -warning message won't appear after inserting UI

Time:11-28

I have a shiny app that dynamically removes and inserts input UI based on user selection. The UI generated by selectingchoice1 and choice2 share part of their input fields. I wanted to use the shinyvalidate package to add some validation rules that can apply to the shared inputs. In the following example, the user can make a selection on the sidebar. Once a choice is made, the div with ID "content" on the main panel will be deleted and a new div will be inserted. The rules seem to be working, but unless I type something in the input field first, the red warning message won't appear when I switch choices.

enter image description here

library(shiny)
library(glue)
library(shinyvalidate)

ui <- fluidPage(
  sidebarPanel(
  selectInput("select", label = "select", choices = c("", "choice1", "choice2"))
  ),
  mainPanel(id = "main",
            tags$div(id = "content"))
)


server <- function(input, output) {

  # validate input
  iv <- InputValidator$new()
  iv$add_rule("input", sv_required())
  iv$enable()

  
  
  observeEvent(input$select, {
  
    if(input$select == "choice1"){
      removeUI("#content")
      insertUI("#main", ui = tags$div(
        id = "content", 
        textInput("input", "input")))
    } 
    if(input$select == "choice2"){
      removeUI("#content")
      insertUI("#main", ui = tags$div(
        id = "content", 
        textInput("input", "input")))
    }

      })
  

}

# Run the application 
shinyApp(ui = ui, server = server)

CodePudding user response:

This works by triggering iv$enable after the observeEvent has finished its work (is "invalidated" is the correct wording I think).

server <- function(input, output) {
  
  # validate input
  iv <- InputValidator$new()
  iv$add_rule("input", sv_required())
  
  Validate <- reactiveVal(NULL)
  
  observeEvent(input$select, {
    
    iv$disable()
    
    if(input$select == "choice1"){
      removeUI("#content")
      insertUI("#main", ui = tags$div(
        id = "content", 
        textInput("input", "input")))
    } 
    if(input$select == "choice2"){
      removeUI("#content")
      insertUI("#main", ui = tags$div(
        id = "content", 
        textInput("input", "input")))
    }
    
    Validate(TRUE)
    
  })
  
  observeEvent(Validate(), {
    iv$enable()
    Validate(NULL)
  })
  
}

EDIT

I don't know why, but you have to set immediate = TRUE in both removeUI and insertUI:

    if(input$select == "choice1"){
      removeUI("#content", immediate = TRUE)
      insertUI("#main", ui = tags$div(
        id = "content", 
        textInput("input", "input")), immediate = TRUE)
    } 
    if(input$select == "choice2"){
      removeUI("#content", immediate = TRUE)
      insertUI("#main", ui = tags$div(
        id = "content", 
        textInput("input", "input")), immediate = TRUE)
    }
  • Related