Skip to content

Conversation

@mnaegelin
Copy link

I had the issue of dynamically generated textInputs, where the user can click on a button to create resp. delete input fields. If the field exists, it is required, but if it is deleted I wanted to remove also the corresponding rules - otherwise the validator would always stay FALSE. Thus I added the method remove_rules(inputId) which simply removes all rules with the corresponding inputId from the validator, and re-enables it if necessary to update the displayed feedback.

Not sure the added method extrapolates well across all scenarios, but it worked for my use case and I think this might also be useful for issue #77 and potentially #71, so I thought I'd share.

example use case:

library(shiny)
library(shinyjs)
library(shinyvalidate)

ui <- fluidPage(
  shinyjs::useShinyjs(),
  
  textInput('author_1', "Author 1", "", placeholder = "Last name, first name"),
  uiOutput("additional_authors"),
  actionButton("add_author_btn", "Add author"),
  actionButton("del_author_btn", "Delete author", class = "btn btn-danger"),
  p('Check if the validation rules are passed:'),
  verbatimTextOutput('check_iv')
)

server <- function(input, output, session) {
  iv <- InputValidator$new()
  iv$add_rule("author_1", sv_required())
  iv$enable()
  
  # Keep track of the number of authors
  author_count <- reactiveVal(1)
  
  # Enable delete button only if there are more than 1 authors
  observe({
    shinyjs::toggleState(id = "del_author_btn", condition = author_count() > 1)
  })
  
  # Add author input if add button is clicked
  observeEvent(input$add_author_btn, {
    author_count(author_count() + 1)
    author_id <- paste0('author', author_count())
    insertUI(
      selector = "#additional_authors",
      where = "beforeBegin",
      ui = div(id = author_id,
               textInput(author_id,
                     paste0("Author ", author_count()), 
                     "", placeholder = "Last name, first name"))
    )
    # add validation rule
    iv$add_rule(author_id, sv_required())
  })
  
  # Delete author input if delete button is clicked 
  observeEvent(input$del_author_btn, {
    author_id <- paste0('author', author_count())
    removeUI(selector = paste0("#", author_id))
    # remove the corresponding author rules
    iv$remove_rules(author_id)
    author_count(author_count() - 1)
  })
  
  # Check the output of iv$is_valid()
  output$check_iv <- renderPrint({
    iv$is_valid()
  })
}

shinyApp(ui, server)

@CLAassistant
Copy link

CLAassistant commented Feb 19, 2025

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants