Skip to contents

Validate a Shiny input and send validation messages to the client. The message appears both in the input widget and in the output element that calls validate_input.

Usage

validate_input(
  inputId,
  condition = function(x) TRUE,
  message = "Check the input",
  session = shiny::getDefaultReactiveDomain()
)

need_input(
  inputId,
  condition = function(x) TRUE,
  message = "Check the input",
  session = shiny::getDefaultReactiveDomain()
)

use_validate_input_js()

Arguments

inputId

(character) Character of input ID(s) to validate

condition

(logical(1), function(x)) Logical value or function returning logical value. Condition should determine expected state, FALSE throws.

message

(character(1)) Character string of validation message to display.

session

Shiny session object

Value

NULL or shiny.silent.error when condition is not met

Details

  • validate_input():

    Validate a Shiny input and send validation messages to the client. The message appears both in the input widget and in the output element that calls validate_input.

  • need_input(): Validate a Shiny input and returns a message to be used in a shiny::validate() call. The message is sent to the client and appears both in the input widget. To observe the message in the output element, need_input() should be called inside a shiny::validate() call, e.g. via validate(validate_input(...)).

  • use_validate_input_js():

    Include JavaScript for client-side input validation.

Examples

# Only run examples in interactive R sessions
options(device.ask.default = FALSE)

ui <- fluidPage(
  checkboxGroupInput("in1", "Check some letters", choices = head(LETTERS)),
  selectizeInput("in2", "Select a state", choices = c("", state.name)),
  use_validate_input_js(),
  plotOutput("plot")
)

server <- function(input, output) {
  output$plot <- renderPlot({
    validate_input("in1", condition = function(x) length(x) > 0, "Check at least one letter!")
    validate_input("in2", condition = function(x) x != "", "Please choose a state.")
    plot(1:10, main = paste(c(input$in1, input$in2), collapse = ", "))
  })
}

if (interactive()) {
  shinyApp(ui, server)
}

my_module <- module(
  label = "My Module",
  datanames = NULL,
  ui = function(id) {
    ns <- NS(id)
    tagList(
      checkboxGroupInput(ns("letters"), "Select letters:", choices = head(LETTERS), inline = TRUE),
      checkboxGroupInput(ns("letters2"), "Select letters:", choices = head(LETTERS), inline = TRUE),
      tags$h3("Sample plot"),
      plotOutput(ns("plot"))
    )
  },
  server = function(id, data) {
    moduleServer(id, function(input, output, session) {
      output$plot <- renderPlot({
        validate_input(
          "letters",
          condition = function(x) length(x) > 0,
          message = "Select at least one letter."
        )
        validate_input(
          c("letters", "letters2"),
          condition = function(x, y) all(!x %in% y),
          message = "Letters in the first group should not be in the second group."
        )
        tab <- rbind(
          Group1 = as.integer(head(LETTERS) %in% input$letters),
          Group2 = as.integer(head(LETTERS) %in% input$letters2)
        )
        colnames(tab) <- head(LETTERS)
        barplot(
          tab,
          beside = TRUE, legend.text = TRUE, main = "Selected letters per group",
          col = c("steelblue", "tomato")
        )
      })
    })
  }
)

app <- init(
  data = within(teal_data(), iris <- iris),
  modules = my_module
)

if (interactive()) {
  shinyApp(app$ui, app$server)
}
my_module <- module(
  label = "My Module",
  datanames = NULL,
  ui = function(id) {
    ns <- NS(id)
    tagList(
      checkboxGroupInput(ns("letters1"), "Select letters:", choices = head(LETTERS), inline = TRUE),
      checkboxGroupInput(ns("letters2"), "Select letters:", choices = head(LETTERS), inline = TRUE),
      tags$h3("Sample plot"),
      plotOutput(ns("plot"))
    )
  },
  server = function(id, data) {
    moduleServer(id, function(input, output, session) {
      output$plot <- renderPlot({
        validate(
          need_input(
            "letters1",
            condition = function(x) length(x) > 0,
            message = "Select at least one letter."
          ),
          need_input(
            c("letters1", "letters2"),
            condition = function(x, y) all(!x %in% y),
            message = "Letters in the first group should not be in the second group."
          )
        )
        tab <- rbind(
          Group1 = as.integer(head(LETTERS) %in% input$letters1),
          Group2 = as.integer(head(LETTERS) %in% input$letters2)
        )
        colnames(tab) <- head(LETTERS)
        barplot(
          tab,
          beside = TRUE, legend.text = TRUE, main = "Selected letters per group",
          col = c("steelblue", "tomato")
        )
      })
    })
  }
)

app <- init(
  data = within(teal_data(), iris <- iris),
  modules = my_module
)

if (interactive()) {
  shinyApp(app$ui, app$server)
}