11

I'm currently trying to find a way to hide/show an entire box() element (and everything inside) in R Shiny. I want to create a maybe a button which allows the user to expand a specifict box and then to hide it with the same (or even different) button. I do not want to use conditionalPanel, as my application is really big and it creates some problems.

A sample code can be found below:

library(shiny)
library(shinydashboard)
library(collapsibleTree)
require(colorspace)
# Dataset is from https://community.tableau.com/docs/DOC-1236
load(system.file("extdata/Superstore_Sales.rda", package = "collapsibleTree"))
# For the sake of speed, let's only plot sales in Ontario
Superstore_Sales <- Superstore_Sales[Superstore_Sales$Region=="Ontario",]

# Define UI for application that draws a collapsible tree
ui <- fluidPage(

  # Application title
  titlePanel("Collapsible Tree Example 3: Gradient Mapping"),

  # Sidebar with a select input for the root node
  sidebarLayout(
    sidebarPanel(

      tags$a(href = "https://community.tableau.com/docs/DOC-1236", "Sample dataset from Tableau")
    ),

    # Show a tree diagram with the selected root node
    mainPanel(
      box(title="Tree Output",width='800px',
        collapsibleTreeOutput("plot", height = "500px")
      ),
      box(title="Input",
        selectInput(
          "hierarchy", "Tree hierarchy",
          choices = c(
            "Customer Segment", "Product Category", "Product Sub-Category",
            "Order Priority", "Product Container"
          ),
          selected = c("Customer Segment","Product Category", "Product Sub-Category"),
          multiple = TRUE
        ),
        selectInput(
          "fill", "Node color",
          choices = c("Order Quantity", "Sales", "Unit Price"),
          selected = "Sales"
        )


      )  
    )
  )
)

# Define server logic required to draw a collapsible tree diagram
server <- function(input, output) {
  output$plot <- renderCollapsibleTree({
    collapsibleTreeSummary(
      Superstore_Sales,
      hierarchy = input$hierarchy,
      root = input$fill,
      attribute = input$fill
    )
  })
}

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

The main idea is to have a button(or buttons) that belong to each box and hide/show only that specific box. Maybe it's possible with shinyjs, but I can't seem to comprehend how it should work with my current structure.

Yordan Ivanov
  • 329
  • 1
  • 3
  • 14

2 Answers2

29

Here's a minimal example that you can extend into your actual application.

It uses shinyjs to show/hide the box. The key is to give the box an id, and then use that id value in the show/hide functions

library(shiny)
library(shinydashboard)
library(shinyjs)

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            useShinyjs()    ## IMPORTANT: so shiny knows to use the shinyjs library
        ),
        mainPanel(
            box(id = "myBox", title = "Tree Output", width = '800px',
                    selectInput(inputId = "myInput", label = "my input", choices = c(letters))
                    ),
            actionButton(inputId = "button", label = "show / hide")
        )
    )
)

server <- function(input, output){

    ## observe the button being pressed
    observeEvent(input$button, {
        
        if(input$button %% 2 == 1){
            shinyjs::hide(id = "myBox")
        }else{
            shinyjs::show(id = "myBox")
        }
    })
}

shinyApp(ui, server)
SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
10

Instead of checking if its divisible by 2 why not use toggle functionality within shinyjs

library(shiny)
library(shinydashboard)
library(shinyjs)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      useShinyjs()
    ),
    mainPanel(
      box(id = "myBox", title = "Tree Output", width = '800px',
          selectInput(inputId = "myInput", label = "my input", choices = c(letters))
      ),
      actionButton(inputId = "button", label = "show / hide")
    )
  )
)

server <- function(input, output){

  ## observe the button being pressed
  observeEvent(input$button, {
    shinyjs::toggle("myBox")
  })
}

shinyApp(ui, server)
Pork Chop
  • 28,528
  • 5
  • 63
  • 77
  • 1
    it's just a coding habit I haven't grown out of yet – SymbolixAU Jun 28 '17 at 12:22
  • 1
    The answer given by @SymbolixAU is also useful for when you are dealing with input selection dropdowns instead of buttons. (For future readers). – datanalyst May 04 '18 at 15:44
  • The answer given by @SymbolixAU also allows to initiate in a hidden state when using `input$button %% 2 == 0` instead of `input$button %% 2 == 1` – martin May 24 '23 at 08:45