Captures messages from InputValidator
objects and collates them
into one message passed to validate
.
Details
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.
shinyvalidate::InputValidator
allows to validate input elements
and to display specific messages in their respective input widgets.
validate_inputs
provides a hybrid solution.
Given an InputValidator
object, messages corresponding to inputs that fail validation
are extracted and placed in one validation message that is passed to a validate
/need
call.
This way the input validator
messages are repeated in the output.
The ...
argument accepts any number of InputValidator
objects
or a nested list of such objects.
If validators
are passed directly, all their messages are printed together
under one (optional) header message specified by header
. If a list is passed,
messages are grouped by 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 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),
tags$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", function(x) {
if (as.integer(x) %% 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", function(x) {
if (length(x) > 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(faithful$eruptions ~ faithful$waiting,
las = 1, pch = 16,
col = input[["color"]], cex = input[["size"]]
)
})
}
if (interactive()) {
shinyApp(ui, server)
}