Search code examples
rshinyshiny-reactivity

checkboxGroupInput delete table output in a shiny app


I'm creating a shiny app whose selections in the checkboxgroup return a table with filtered data after clicking on the actionbutton, as shown in the example below. My question is how do I include the functionality, after generating the table when I click again on any checkbox the tables are deleted until the user clicks on the actionbutton again.

library(shiny)
library(DT)
library(dplyr)

ui <- fluidPage(

      checkboxGroupInput(inputId = "checkboxGroup1", label = "checkboxGroup1", choices = list(5.0, 4.6)),
      checkboxGroupInput(inputId = "checkboxGroup2", label = "checkboxGroup2", choices = list(3.4, 3.6)),
      checkboxGroupInput(inputId = "checkboxGroup3", label = "checkboxGroup3", choices = list(0.2, 1.5)),
      checkboxGroupInput(inputId = "checkboxGroup4", label = "checkboxGroup4", choices = list("setosa", "virginica")),
      actionButton('action',label = 'action'),

      mainPanel(
          dataTableOutput("table1")
        )
    )


# Define server logic required to draw a histogram
server <- function(input, output) {
  
  filter_data <- eventReactive(input$action, {
    
    data <- iris
    
    Sys.sleep(5) #included to delay the output

    data %>% 
      {if (is.null(input$checkboxGroup1) == FALSE) filter(., Sepal.Length %in% input$checkboxGroup1) else .} %>% 
      {if (is.null(input$checkboxGroup2) == FALSE) filter(., Sepal.Width %in% input$checkboxGroup2) else .} %>% 
      {if (is.null(input$checkboxGroup3) == FALSE) filter(., Petal.Width %in% input$checkboxGroup3) else .} %>%
      {if (is.null(input$checkboxGroup4) == FALSE) filter(., Species %in% input$checkboxGroup4) else .}

  })
  
  output$table1 <- renderDataTable(
    filter_data()
  )
  
}

# Run the application 
shinyApp(ui = ui, server = server)

Edited: added 'Sys.sleep(5)' to delay the output. Just hiding the table would not solve this case, if the action button is pressed before the update.


Solution

  • Here's an option using shinyjs. First create a reactive expression that is dependent on all checkbox inputs. We can use shinyjs::hide to hide the DT anytime a checkbox is selected. Then use shinyjs::show to show the table when the action button is clicked.

    Demo w/ updated basic UI

    enter image description here

    library(shiny)
    library(DT)
    library(dplyr)
    library(shinyjs)
    
    ui <- fluidPage(
        useShinyjs(), # include shinyjs here
        checkboxGroupInput(inputId = "checkboxGroup1", label = "checkboxGroup1", choices = list(5.0, 4.6)),
        checkboxGroupInput(inputId = "checkboxGroup2", label = "checkboxGroup2", choices = list(3.4, 3.6)),
        checkboxGroupInput(inputId = "checkboxGroup3", label = "checkboxGroup3", choices = list(0.2, 1.5)),
        checkboxGroupInput(inputId = "checkboxGroup4", label = "checkboxGroup4", choices = list("setosa", "virginica")),
        actionButton('action',label = 'action'),
    
        mainPanel(
            dataTableOutput("table1")
          )
    )
    
    # Define server logic required to draw a histogram
    server <- function(input, output) {
      
      filter_data <- eventReactive(input$action, {
        data <- iris
        data %>% 
          {if (is.null(input$checkboxGroup1) == FALSE) filter(., Sepal.Length %in% input$checkboxGroup1) else .} %>% 
          {if (is.null(input$checkboxGroup2) == FALSE) filter(., Sepal.Width %in% input$checkboxGroup2) else .} %>% 
          {if (is.null(input$checkboxGroup3) == FALSE) filter(., Petal.Width %in% input$checkboxGroup3) else .} %>%
          {if (is.null(input$checkboxGroup4) == FALSE) filter(., Species %in% input$checkboxGroup4) else .}
      })
      
      obs_checkboxes = reactive({
        list(input$checkboxGroup1,input$checkboxGroup2,input$checkboxGroup3,input$checkboxGroup4)
      })
    
      observeEvent(obs_checkboxes(), {
        hide("table1")
      })
      
      observeEvent(input$action, {
        show("table1")
      })
      
      output$table1 <- renderDataTable(
        filter_data()
      )
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)