0

How can we add a "Clear" button to reset check box values to NULL in an app with a dynamic UI?

Example data:

df <- data.frame(
  "Group" = c("Group A", "Group B", "Group A", "Group A", "Group B"),
  "Name" = c("Bob", "Paul", "Peter", "Emma", "John"),
  "Value" = seq(1,10, length.out=5),
  stringsAsFactors = F
)

df
    Group  Name Value
1 Group A   Bob  1.00
2 Group B  Paul  3.25
3 Group A Peter  5.50
4 Group A  Emma  7.75
5 Group B  John 10.00

I create one tab per Group and a checkbox of Name values:

library(shiny)

# UI
ui <- fluidPage(
  mainPanel(
    uiOutput('mytabs')
  )
)

# SERVER
server <- function(input, output, session) {

  Tabs_titles = unique(df$Group)

  # Dynamic UI
  output$mytabs <- renderUI({
    myTabs <- lapply(Tabs_titles,
                     function(x){
                       tabPanel(title = x,
                                checkboxGroupInput(inputId = paste0("checkboxID_", x),
                                                   label = "My Checkbox",
                                                   choices = df %>% subset(Group == x) %>% pull(Name),
                                                   selected = df %>% subset(Group == x) %>% pull(Name)
                                ),
                                checkboxInput(paste0("clear_", x), "Clear"),
                                tableOutput(paste0("my_Table_", x))
                       )
                     }
    )

    do.call(tabsetPanel, myTabs)

  })


  observe(
    lapply(Tabs_titles,
           function(x){
             checked_names <- reactive({input[[paste0("checkboxID_", x)]]})

             # Table
             output[[paste0("my_Table_", x)]] <-renderTable({
               df %>%
               subset(Group == x & Name %in% checked_names())
             })

             # Clear button here
             observe({
               if(req(input[[paste0("clear_", x)]]) == TRUE){
                 updateCheckboxGroupInput(
                  session,
                  paste0("checkboxID_", x),
                  choices = df %>% subset(Group == x) %>% pull(Name),
                  selected = NULL
                )
               }
             })
           }
    )
  )
}


shinyApp(ui, server)

But when checked, the Clear box does not trigger anything.

u31889
  • 331
  • 1
  • 9

1 Answers1

0

From the online help for updateCheckboxGroupInput: Any arguments with NULL values will be ignored; they will not result in any changes to the input object on the client. [My emphasis.]

You have selected = NULL. Perhaps selected=c() will give you what you want?

Edit Contradicting what I wrote above, this post suggests a different solution.

Edit 2 This proof-of-concept example works as expected. So it's likely you have a second issue in your code which is interacting with the working solution. As I may have mentioned before: using modules would make your life easier: each module would be responsible for clearing its own checkboxGroupInput, so indexing would not be a concern.

library(shiny)

ui <- fluidPage(
   titlePanel("Clear checkboxGroup Test"),
   sidebarLayout(
      sidebarPanel(
        actionButton("clear", "Clear")
      ),
      mainPanel(
        checkboxGroupInput("group", "The Beatles", choices=c("John", "Paul", "George", "Ringo"))
      )
   )
)

server <- function(input, output, session) {
  observeEvent(input$clear, {
    updateCheckboxGroupInput(session, "group", choices=c("John", "Paul", "George", "Ringo"), selected=NULL)
  })
}

shinyApp(ui = ui, server = server)
Limey
  • 10,234
  • 2
  • 12
  • 32
  • Still nothing happening with `selected=c()` or without mentioning `selected` at all (equivalent to `selected = NULL` as you mentioned). – u31889 Jun 17 '20 at 12:54
  • Using an `actionButton` with `if(req(input[[paste0("clear_", x)]]) > 0){...}` does not trigger anything neither. – u31889 Jun 17 '20 at 13:11
  • The actionButton does trigger. However, updateCheckboxGroupInput does not update anything. – JohannesNE Jun 17 '20 at 13:13
  • The toy example also works with `selected=c()` in place of `selected=NULL`. I'm confident there's more than one issue in the OP's code. – Limey Jun 17 '20 at 13:25
  • I am able to make the button work as well for static UI. I agree, that modules would help with indexing. – u31889 Jun 17 '20 at 13:31
  • @JohannesNE, Maybe the `updateCheckboxGroupInput` is not updating anything due to the if statement? I find it weird to be forced to use `req()` for calling the `input$button`. Maybe it is related – u31889 Jun 17 '20 at 13:34