Search code examples
rshinyshinydashboard

Use actionbutton to display box() and table initially hidden, but then use it only for the subseting of the table


I want to create a shinydashboard in which I have in the sidebar a selectinput() with all the column names of iris dataset, in the main body inside a box() we have a datatable of iris which is subseted by the selectInput(), and an actiobutton() below it out of the box.

When the app starts neither the box not the table are displayed. when I click on the actionbutton() the box with the subseted table are displayed. Then if I change the selectInput() choices nothing happens, but then if I click on the actionbutton() the subset takes place. The box remains there for the whole period now and never hidden again.

library(shiny)
library(shinydashboard)
library(DT)

# Define UI
ui <- dashboardPage(
  dashboardHeader(title = "Subset Iris Dataset"),
  dashboardSidebar(
    selectInput("columns_selected", "Select Columns", choices = colnames(iris), multiple = TRUE)
  ),
  dashboardBody(
    
        fluidRow(
          box(
            title = "Subsetted Iris Data",
            width = 12,
            DTOutput("subset_table"),
          ),
          actionButton("subset_button", "Subset Data")
        )
  )
)

# Define server logic
server <- function(input, output) {
  # Load the iris dataset
  data <- iris
  
  observeEvent(input$subset_button, {
    columns_selected <- input$columns_selected
    if (!is.null(columns_selected)) {
      data_subset <- data[, columns_selected, drop = FALSE]
      output$subset_table <- renderDT({
        datatable(data_subset)
      })
      show("subset_table")
    }
  })
  
  observe({
    hide("subset_table")
  })
}

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

Solution

  • If you want the table to be hidden when changing the selections, you can hide it in an observer. Try this

    library(shiny)
    library(shinydashboard)
    library(DT)
    library(shinyjs)
    
    # Define UI
    ui <- dashboardPage(
      dashboardHeader(title = "Subset Iris Dataset"),
      dashboardSidebar(
        selectInput("columns_selected", "Select Columns", choices = colnames(iris), multiple = TRUE)
      ),
      dashboardBody(
        useShinyjs(),
        fluidRow(
          box(
            title = "Subsetted Iris Data",
            width = 12,
            DTOutput("subset_table"),
          ),
          actionButton("subset_button", "Subset Data")
        )
      )
    )
    
    # Define server logic
    server <- function(input, output) {
      # Load the iris dataset
      data <- iris
      
      data_subset <- eventReactive(input$subset_button, { 
        columns_selected <- input$columns_selected
        if (is.null(columns_selected)) { df <- NULL
        }else {
          df <- data[, columns_selected, drop = FALSE]
        }
        df
      })
      
      observeEvent(input$subset_button, {
        if (!is.null(input$columns_selected)) {
          show("subset_table")
        }
      })
      
      output$subset_table <- renderDT({
        datatable(data_subset())
      })
      
      observeEvent(input$columns_selected, {
        shinyjs::hide("subset_table")
      })
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)