% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/validate_inputs.R
\name{validate_inputs}
\alias{validate_inputs}
\title{Send input validation messages to output}
\usage{
validate_inputs(..., header = "Some inputs require attention")
}
\arguments{
\item{...}{either any number of \code{InputValidator} objects
or an optionally named, possibly nested \code{list} of \code{InputValidator}
objects, see \code{Details}}

\item{header}{(\code{character(1)}) generic validation message; set to NULL to omit}
}
\value{
Returns NULL if the final validation call passes and a \code{shiny.silent.error} if it fails.
}
\description{
Captures messages from \code{InputValidator} objects and collates them
into one message passed to \code{validate}.
}
\details{
\code{shiny::validate} is used to withhold rendering of an output element until
certain conditions are met and to print a validation message in place
of the output element.
\code{shinyvalidate::InputValidator} allows to validate input elements
and to display specific messages in their respective input widgets.
\code{validate_inputs} provides a hybrid solution.
Given an \code{InputValidator} object, messages corresponding to inputs that fail validation
are extracted and placed in one validation message that is passed to a \code{validate}/\code{need} call.
This way the input \code{validator} messages are repeated in the output.

The \code{...} argument accepts any number of \code{InputValidator} objects
or a nested list of such objects.
If \code{validators} are passed directly, all their messages are printed together
under one (optional) header message specified by \code{header}. If a list is passed,
messages are grouped by \code{validator}. The list's names are used as headers
for their respective message groups.
If neither of the nested list elements is named, a header message is taken from \code{header}.
}
\examples{
library(shiny)
library(shinyvalidate)

ui <- fluidPage(
  selectInput("method", "validation method", c("sequential", "combined", "grouped")),
  sidebarLayout(
    sidebarPanel(
      selectInput("letter", "select a letter:", c(letters[1:3], LETTERS[4:6])),
      selectInput("number", "select a number:", 1:6),
      br(),
      selectInput("color", "select a color:",
        c("black", "indianred2", "springgreen2", "cornflowerblue"),
        multiple = TRUE
      ),
      sliderInput("size", "select point size:",
        min = 0.1, max = 4, value = 0.25
      )
    ),
    mainPanel(plotOutput("plot"))
  )
)

server <- function(input, output) {
  # set up input validation
  iv <- InputValidator$new()
  iv$add_rule("letter", sv_in_set(LETTERS, "choose a capital letter"))
  iv$add_rule("number", ~ if (as.integer(.) \%\% 2L == 1L) "choose an even number")
  iv$enable()
  # more input validation
  iv_par <- InputValidator$new()
  iv_par$add_rule("color", sv_required(message = "choose a color"))
  iv_par$add_rule("color", ~ if (length(.) > 1L) "choose only one color")
  iv_par$add_rule(
    "size",
    sv_between(
      left = 0.5, right = 3,
      message_fmt = "choose a value between {left} and {right}"
    )
  )
  iv_par$enable()

  output$plot <- renderPlot({
    # validate output
    switch(input[["method"]],
      "sequential" = {
        validate_inputs(iv)
        validate_inputs(iv_par, header = "Set proper graphical parameters")
      },
      "combined" = validate_inputs(iv, iv_par),
      "grouped" = validate_inputs(list(
        "Some inputs require attention" = iv,
        "Set proper graphical parameters" = iv_par
      ))
    )

    plot(eruptions ~ waiting, faithful,
      las = 1, pch = 16,
      col = input[["color"]], cex = input[["size"]]
    )
  })
}

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

}
\seealso{
\code{\link[shinyvalidate:InputValidator]{shinyvalidate::InputValidator}}, \code{\link[shiny:validate]{shiny::validate}}
}
