### Install shinyvalidate Source: https://github.com/rstudio/shinyvalidate/blob/main/README.md Commands to install the package from CRAN or GitHub. ```r install.packages("shinyvalidate") ``` ```r remotes::install_github("rstudio/shinyvalidate") ``` -------------------------------- ### Implement basic input validation in Shiny Source: https://github.com/rstudio/shinyvalidate/blob/main/README.md A complete example demonstrating how to initialize an InputValidator, add rules for required fields and email formats, and enable validation in a Shiny server function. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("name", "Name"), textInput("email", "Email") ) server <- function(input, output, session) { iv <- InputValidator$new() iv$add_rule("name", sv_required()) iv$add_rule("email", sv_required()) iv$add_rule("email", sv_email()) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Shiny Module Validation with shinyvalidate Source: https://context7.com/rstudio/shinyvalidate/llms.txt Integrate shinyvalidate with Shiny modules. Modules can create and return their own validators, which can then be enabled or added as child validators by the calling application. This example shows a reusable email input module with its own validation logic. ```r library(shiny) library(shinyvalidate) # Module UI email_input_ui <- function(id, label = "Email") { ns <- NS(id) textInput(ns("email"), label) } # Module Server - returns value and validator email_input_server <- function(id, required = TRUE) { moduleServer(id, function(input, output, session) { # Create validator inside module iv <- InputValidator$new() if (required) { iv$add_rule("email", sv_required()) } iv$add_rule("email", sv_email()) # Return value accessor and validator to caller list( value = reactive(input$email), iv = iv ) }) } # App UI ui <- fluidPage( textInput("name", "Name"), email_input_ui("primary_email", "Primary Email"), email_input_ui("secondary_email", "Secondary Email (optional)"), actionButton("submit", "Submit"), textOutput("result") ) # App Server server <- function(input, output, session) { # Initialize modules primary <- email_input_server("primary_email", required = TRUE) secondary <- email_input_server("secondary_email", required = FALSE) # Create parent validator iv <- InputValidator$new() iv$add_rule("name", sv_required()) iv$add_validator(primary$iv) iv$add_validator(secondary$iv) iv$enable() output$result <- renderText({ req(iv$is_valid()) emails <- c(primary$value()) if (nzchar(secondary$value())) { emails <- c(emails, secondary$value()) } paste("Hello", input$name, "- Emails:", paste(emails, collapse = ", ")) }) } shinyApp(ui, server) ``` -------------------------------- ### Implement InputValidator in Shiny Source: https://context7.com/rstudio/shinyvalidate/llms.txt Demonstrates the basic workflow of creating an InputValidator, adding rules, enabling feedback, and guarding reactive outputs with is_valid(). ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("name", "Name"), textInput("email", "Email"), numericInput("age", "Age", value = NULL), textOutput("greeting") ) server <- function(input, output, session) { # Create an InputValidator object iv <- InputValidator$new() # Add validation rules iv$add_rule("name", sv_required()) iv$add_rule("email", sv_required()) iv$add_rule("email", sv_email()) iv$add_rule("age", sv_required()) iv$add_rule("age", sv_gte(18, message_fmt = "Must be at least {rhs} years old")) # Start displaying errors in the UI iv$enable() output$greeting <- renderText({ # Don't proceed if any input is invalid req(iv$is_valid()) paste0("Hello, ", input$name, "! You are ", input$age, " years old.") }) } shinyApp(ui, server) ``` -------------------------------- ### Validate URL format with sv_url() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Ensures inputs contain valid HTTP, HTTPS, or FTP protocols. Use sv_optional() if the field is not mandatory. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("homepage", "Homepage URL"), textInput("portfolio", "Portfolio URL") ) server <- function(input, output, session) { iv <- InputValidator$new() iv$add_rule("homepage", sv_required()) iv$add_rule("homepage", sv_url()) iv$add_rule("portfolio", sv_optional()) iv$add_rule("portfolio", sv_url(message = "Please enter a valid portfolio URL")) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Validate Email Addresses Source: https://context7.com/rstudio/shinyvalidate/llms.txt Uses sv_email() to verify email format, demonstrating both required and optional usage. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("primary_email", "Primary Email"), textInput("backup_email", "Backup Email (optional)") ) server <- function(input, output, session) { iv <- InputValidator$new() # Required email iv$add_rule("primary_email", sv_required()) iv$add_rule("primary_email", sv_email()) # Optional email with custom error message iv$add_rule("backup_email", sv_optional()) iv$add_rule("backup_email", sv_email(message = "Please enter a valid backup email")) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Validate Equality with sv_equal and sv_not_equal Source: https://context7.com/rstudio/shinyvalidate/llms.txt Use these rules to enforce that an input matches or avoids specific values. The message_fmt argument supports placeholders like {rhs} for the comparison value. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( numericInput("confirm_code", "Enter confirmation code (1234)", value = NULL), textInput("username", "Username"), numericInput("score", "Score", value = NULL) ) server <- function(input, output, session) { iv <- InputValidator$new() # Must equal a specific value iv$add_rule("confirm_code", sv_required()) iv$add_rule("confirm_code", sv_equal(1234, message_fmt = "Invalid confirmation code")) # Must not equal a reserved value iv$add_rule("username", sv_required()) iv$add_rule("username", sv_not_equal("admin", message_fmt = "Username '{rhs}' is reserved")) # Score must not be zero iv$add_rule("score", sv_required()) iv$add_rule("score", sv_not_equal(0, message_fmt = "Score cannot be zero")) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Check if Input Has Value with input_provided() Source: https://context7.com/rstudio/shinyvalidate/llms.txt The `input_provided()` utility function checks if an input value represents actual user-provided data. It returns `FALSE` for `NULL`, empty strings, `NA`-only vectors, and unclicked action buttons, distinguishing it from `isTruthy()` in certain cases like logical `FALSE`. ```r library(shiny) library(shinyvalidate) # input_provided() returns FALSE for: input_provided(NULL) # FALSE - NULL value input_provided("") # FALSE - empty string input_provided(character(0)) # FALSE - empty vector input_provided(NA) # FALSE - single NA input_provided(c(NA, NA)) # FALSE - all NA values input_provided(c("", "")) # FALSE - all empty strings # input_provided() returns TRUE for: input_provided("hello") # TRUE - non-empty string input_provided(0) # TRUE - numeric zero input_provided(FALSE) # TRUE - logical FALSE (different from isTruthy) input_provided(c(1, NA)) # TRUE - vector with some non-NA values input_provided(list(a = 1)) # TRUE - non-empty list # Use in custom validation rules ui <- fluidPage( textInput("optional_field", "Optional Field"), textOutput("status") ) server <- function(input, output, session) { output$status <- renderText({ if (input_provided(input$optional_field)) { paste("You entered:", input$optional_field) } else { "No value provided" } }) } shinyApp(ui, server) ``` -------------------------------- ### Deferred Validation with enable() and disable() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Control when validation feedback is displayed by using `iv$enable()` and `iv$disable()`. This is useful for forms with explicit submit buttons, deferring validation until the user attempts to submit. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("name", "Name *"), textInput("email", "Email *"), checkboxGroupInput("interests", "Interests (select at least 2) *", choices = c("Sports", "Music", "Technology", "Travel")), checkboxInput("terms", "I accept the terms and conditions *"), helpText("* Required"), actionButton("submit", "Submit", class = "btn-primary"), actionButton("reset", "Reset") ) server <- function(input, output, session) { iv <- InputValidator$new() iv$add_rule("name", sv_required()) iv$add_rule("email", sv_required()) iv$add_rule("email", sv_email()) iv$add_rule("interests", ~ if (length(.) < 2) "Select at least 2 interests") iv$add_rule("terms", sv_required()) iv$add_rule("terms", ~ if (!isTRUE(.)) "You must accept the terms") # Don't enable validation immediately - wait for submit observeEvent(input$submit, { if (iv$is_valid()) { iv$disable() # Clear validation messages showModal(modalDialog( title = "Success", "Form submitted successfully!", easyClose = TRUE )) } else { iv$enable() # Show validation feedback on first submit attempt showNotification("Please fix the errors and try again", type = "error") } }) observeEvent(input$reset, { iv$disable() # Hide validation messages updateTextInput(session, "name", value = "") updateTextInput(session, "email", value = "") updateCheckboxGroupInput(session, "interests", selected = character(0)) updateCheckboxInput(session, "terms", value = FALSE) }) } shinyApp(ui, server) ``` -------------------------------- ### Validate Patterns with sv_regex Source: https://context7.com/rstudio/shinyvalidate/llms.txt Validate inputs against regular expression patterns. Supports standard regex options like ignore.case. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("phone", "Phone (XXX-XXX-XXXX)"), textInput("zip", "ZIP Code"), textInput("username", "Username (alphanumeric only)") ) server <- function(input, output, session) { iv <- InputValidator$new() # Phone number pattern iv$add_rule("phone", sv_required()) iv$add_rule("phone", sv_regex( pattern = "^[0-9]{3}-[0-9]{3}-[0-9]{4}$", message = "Phone must be in format XXX-XXX-XXXX" )) # ZIP code (5 digits or 5+4 format) iv$add_rule("zip", sv_required()) iv$add_rule("zip", sv_regex( pattern = "^[0-9]{5}(-[0-9]{4})?$", message = "Invalid ZIP code format" )) # Alphanumeric username (case insensitive) iv$add_rule("username", sv_required()) iv$add_rule("username", sv_regex( pattern = "^[a-zA-Z0-9]+$", message = "Username can only contain letters and numbers", ignore.case = TRUE )) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Validate numeric comparisons with sv_gt, sv_gte, sv_lt, sv_lte Source: https://context7.com/rstudio/shinyvalidate/llms.txt Compares input values against a threshold using greater than, less than, or equality operators. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( numericInput("age", "Age", value = NULL), numericInput("discount", "Discount %", value = NULL), numericInput("quantity", "Quantity", value = NULL), numericInput("max_items", "Max Items", value = NULL) ) server <- function(input, output, session) { iv <- InputValidator$new() # Greater than: value > 0 iv$add_rule("age", sv_required()) iv$add_rule("age", sv_gt(0, message_fmt = "Age must be greater than {rhs}")) # Greater than or equal: value >= 0 iv$add_rule("discount", sv_required()) iv$add_rule("discount", sv_gte(0)) # Less than: value < 100 iv$add_rule("discount", sv_lt(100, message_fmt = "Discount must be less than {rhs}%")) # Less than or equal: value <= 1000 iv$add_rule("quantity", sv_required()) iv$add_rule("quantity", sv_lte(1000)) # Greater than or equal with integers iv$add_rule("max_items", sv_required()) iv$add_rule("max_items", sv_gte(1, message_fmt = "Must have at least {rhs} item")) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Implement Custom Validation Rules Source: https://context7.com/rstudio/shinyvalidate/llms.txt Define complex validation logic using functions or formulas. Return NULL for success or a string for an error message. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("password", "Password"), textInput("confirm_password", "Confirm Password"), checkboxGroupInput("topics", "Topics (select 2-4)", choices = c("R", "Python", "SQL", "JavaScript", "Go")), dateInput("event_date", "Event Date"), textOutput("result") ) server <- function(input, output, session) { iv <- InputValidator$new() # Custom validation with formula (use . for the input value) iv$add_rule("password", sv_required()) iv$add_rule("password", ~ if (nchar(.) < 8) "Password must be at least 8 characters") iv$add_rule("password", ~ if (!grepl("[0-9]", .)) "Password must contain a number") iv$add_rule("password", ~ if (!grepl("[A-Z]", .)) "Password must contain uppercase letter") # Custom validation with anonymous function iv$add_rule("confirm_password", sv_required()) iv$add_rule("confirm_password", function(value) { if (value != input$password) { "Passwords do not match" } }) # Validate selection count iv$add_rule("topics", function(value) { if (length(value) < 2) { "Please select at least 2 topics" } else if (length(value) > 4) { "Please select no more than 4 topics" } }) # Named function for reusable validation must_be_future_date <- function(value) { if (value <= Sys.Date()) { "Date must be in the future" } } iv$add_rule("event_date", sv_required()) iv$add_rule("event_date", must_be_future_date) iv$enable() output$result <- renderText({ req(iv$is_valid()) "All inputs are valid!" }) } shinyApp(ui, server) ``` -------------------------------- ### Validate Optional Fields Source: https://context7.com/rstudio/shinyvalidate/llms.txt Uses sv_optional() to allow empty inputs while still validating them if a value is provided. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("name", "Name (required)"), textInput("website", "Website (optional)"), textOutput("result") ) server <- function(input, output, session) { iv <- InputValidator$new() iv$add_rule("name", sv_required()) # Website is optional, but if provided must be a valid URL iv$add_rule("website", sv_optional()) iv$add_rule("website", sv_url()) iv$enable() output$result <- renderText({ req(iv$is_valid()) if (nzchar(input$website)) { paste0(input$name, " - ", input$website) } else { input$name } }) } shinyApp(ui, server) ``` -------------------------------- ### Validate integer values with sv_integer() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Verifies that an input is a whole number using the modulo operator. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( numericInput("count", "Item Count", value = NULL), numericInput("batch_size", "Batch Size", value = NULL) ) server <- function(input, output, session) { iv <- InputValidator$new() iv$add_rule("count", sv_required()) iv$add_rule("count", sv_integer(message = "Count must be a whole number")) iv$add_rule("batch_size", sv_required()) iv$add_rule("batch_size", sv_integer()) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Conditional Validation with condition() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Apply validation rules conditionally based on other inputs or reactive state using `condition()`. When the condition evaluates to `FALSE`, all associated rules are bypassed and treated as passing. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( radioButtons("contact_method", "Preferred Contact Method", choices = c("Email", "Phone", "Mail")), textInput("email", "Email Address"), textInput("phone", "Phone Number"), textInput("address", "Mailing Address"), textOutput("result") ) server <- function(input, output, session) { # Create separate validators for each contact method email_iv <- InputValidator$new() email_iv$condition(~ input$contact_method == "Email") email_iv$add_rule("email", sv_required()) email_iv$add_rule("email", sv_email()) phone_iv <- InputValidator$new() phone_iv$condition(~ input$contact_method == "Phone") phone_iv$add_rule("phone", sv_required()) phone_iv$add_rule("phone", sv_regex("^[0-9-]+", "Invalid phone format")) mail_iv <- InputValidator$new() mail_iv$condition(~ input$contact_method == "Mail") mail_iv$add_rule("address", sv_required()) # Parent validator combines all conditional validators iv <- InputValidator$new() iv$add_validator(email_iv) iv$add_validator(phone_iv) iv$add_validator(mail_iv) iv$enable() output$result <- renderText({ req(iv$is_valid()) paste("Contact via:", input$contact_method) }) } shinyApp(ui, server) ``` -------------------------------- ### Validate Set Membership with sv_in_set Source: https://context7.com/rstudio/shinyvalidate/llms.txt Enforce that an input value exists within a predefined set. Use set_limit to control how many values are displayed in error messages. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("grade", "Grade (A, B, C, D, or F)"), selectInput("country", "Country", choices = c("", "USA", "Canada", "Mexico", "UK")), textInput("status", "Status Code") ) server <- function(input, output, session) { iv <- InputValidator$new() # Basic set validation iv$add_rule("grade", sv_required()) iv$add_rule("grade", sv_in_set(c("A", "B", "C", "D", "F"))) # With custom message iv$add_rule("country", sv_required()) iv$add_rule("country", sv_in_set( set = c("USA", "Canada", "Mexico", "UK"), message_fmt = "Please select a valid country from: {values_text}" )) # Numeric set with limit on displayed values iv$add_rule("status", sv_required()) iv$add_rule("status", sv_in_set( set = c(100, 200, 201, 301, 400, 404, 500), set_limit = 4 )) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Validate numeric values with sv_numeric() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Checks if an input is numeric, with optional configuration for NA, NaN, and infinite values. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("price", "Price"), textInput("quantity", "Quantity"), textOutput("total") ) server <- function(input, output, session) { iv <- InputValidator$new() iv$add_rule("price", sv_required()) iv$add_rule("price", sv_numeric(message = "Price must be a number")) iv$add_rule("quantity", sv_required()) iv$add_rule("quantity", sv_numeric( message = "Quantity must be a number", allow_na = FALSE, allow_nan = FALSE, allow_inf = FALSE )) iv$enable() output$total <- renderText({ req(iv$is_valid()) total <- as.numeric(input$price) * as.numeric(input$quantity) paste0("Total: $", format(total, nsmall = 2)) }) } shinyApp(ui, server) ``` -------------------------------- ### Combine Child Validators with add_validator() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Use `add_validator()` to combine multiple `InputValidator` objects. The parent validator is only considered valid if all its child validators are also valid. This is useful for organizing validation logic into sections. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( h4("Personal Information"), textInput("name", "Name"), textInput("email", "Email"), h4("Shipping Address"), textInput("street", "Street"), textInput("city", "City"), textInput("zip", "ZIP Code"), actionButton("submit", "Submit Order") ) server <- function(input, output, session) { # Validator for personal info personal_iv <- InputValidator$new() personal_iv$add_rule("name", sv_required()) personal_iv$add_rule("email", sv_required()) personal_iv$add_rule("email", sv_email()) # Validator for shipping address shipping_iv <- InputValidator$new() shipping_iv$add_rule("street", sv_required()) shipping_iv$add_rule("city", sv_required()) shipping_iv$add_rule("zip", sv_required()) shipping_iv$add_rule("zip", sv_regex("^[0-9]{5}$", "Invalid ZIP code")) # Parent validator combines both sections iv <- InputValidator$new() iv$add_validator(personal_iv) iv$add_validator(shipping_iv) iv$enable() observeEvent(input$submit, { if (iv$is_valid()) { showNotification("Order submitted!", type = "message") } else { showNotification("Please complete all required fields", type = "error") } }) } shinyApp(ui, server) ``` -------------------------------- ### Compose Reusable Validation Rules with compose_rules() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Use `compose_rules` to combine multiple validation rules into a single, reusable function. This is ideal for creating custom validators for specific input types or complex validation logic. ```r library(shiny) library(shinyvalidate) # Create a reusable validation rule for positive even integers positive_even_integer <- function() { compose_rules( sv_required(), sv_integer(), sv_gt(0), ~ if (. %% 2 == 1) "Must be an even number" ) } # Create a reusable password strength validator strong_password <- function(min_length = 8) { compose_rules( sv_required(), ~ if (nchar(.) < min_length) paste("Must be at least", min_length, "characters"), ~ if (!grepl("[A-Z]", .)) "Must contain an uppercase letter", ~ if (!grepl("[a-z]", .)) "Must contain a lowercase letter", ~ if (!grepl("[0-9]", .)) "Must contain a number", ~ if (!grepl("[^A-Za-z0-9]", .)) "Must contain a special character" ) } ui <- fluidPage( numericInput("pair_count", "Number of Pairs (positive even integer)", value = NULL), textInput("password", "Password") ) server <- function(input, output, session) { iv <- InputValidator$new() # Use composed rules iv$add_rule("pair_count", positive_even_integer()) iv$add_rule("password", strong_password(min_length = 10)) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Validate Required Fields Source: https://context7.com/rstudio/shinyvalidate/llms.txt Uses sv_required() to ensure inputs are not empty, supporting custom error messages. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("title", "Title"), selectInput("category", "Category", choices = c("", "A", "B", "C")), actionButton("submit", "Submit") ) server <- function(input, output, session) { iv <- InputValidator$new() # Basic required field with default message "Required" iv$add_rule("title", sv_required()) # Required field with custom message iv$add_rule("category", sv_required(message = "Please select a category")) iv$enable() observeEvent(input$submit, { if (iv$is_valid()) { showNotification("Form submitted successfully!", type = "message") } }) } shinyApp(ui, server) ``` -------------------------------- ### Validate numeric ranges with sv_between() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Ensures a value falls within a specified range, supporting custom messages and inclusive/exclusive boundaries. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( numericInput("rating", "Rating (1-5)", value = NULL, min = 1, max = 5), numericInput("percentage", "Percentage (0-100)", value = NULL), numericInput("temperature", "Temperature (-40 to 50)", value = NULL) ) server <- function(input, output, session) { iv <- InputValidator$new() # Inclusive bounds (default): 1 <= value <= 5 iv$add_rule("rating", sv_required()) iv$add_rule("rating", sv_between(1, 5)) # Custom message format iv$add_rule("percentage", sv_required()) iv$add_rule("percentage", sv_between( left = 0, right = 100, message_fmt = "Value must be between {left}% and {right}%" )) # Exclusive lower bound: -40 < value <= 50 iv$add_rule("temperature", sv_required()) iv$add_rule("temperature", sv_between( left = -40, right = 50, inclusive = c(FALSE, TRUE) )) iv$enable() } shinyApp(ui, server) ``` -------------------------------- ### Skip Remaining Validation Rules with skip_validation() Source: https://context7.com/rstudio/shinyvalidate/llms.txt Use skip_validation() to stop further validation for an input. This is useful for optional fields or special input values. Ensure shiny and shinyvalidate libraries are loaded. ```r library(shiny) library(shinyvalidate) ui <- fluidPage( textInput("code", "Promo Code (optional)"), textOutput("result") ) server <- function(input, output, session) { iv <- InputValidator$new() # Custom rule that skips validation for special values iv$add_rule("code", function(value) { # Skip all validation if empty or special code if (!nzchar(value) || value == "SKIP") { return(skip_validation()) } # Otherwise validate format if (!grepl("^[A-Z]{4}[0-9]{4}$", value)) { return("Code must be 4 letters followed by 4 digits (e.g., SAVE2024)") } }) iv$enable() output$result <- renderText({ req(iv$is_valid()) if (nzchar(input$code) && input$code != "SKIP") { paste("Promo code applied:", input$code) } else { "No promo code" } }) } shinyApp(ui, server) ``` -------------------------------- ### skip_validation() Source: https://context7.com/rstudio/shinyvalidate/llms.txt A function used within custom validation rules to signal that all remaining validation rules for a specific input should be skipped. ```APIDOC ## skip_validation() ### Description Returns a special value that signals shinyvalidate to skip all remaining validation rules for an input. This is primarily used internally by `sv_optional()` but can be utilized in custom rule functions to bypass further checks. ### Usage `skip_validation()` ### Returns A special sentinel value recognized by the InputValidator object to terminate the validation chain for the current input. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.