'How to reactively show and hide an object in a sidebar panel?

I am trying to conditionally (reactively) render a selectInput() box in the sidebar panel in an App. Below is excerpted reproducible code.

Basically, if the user opts to view "Strats", then the selectInput() box should appear in the sidebar panel. Otherwise, the selectInput() box should remain hidden. Default condition should be hidden until "Strats" is selected.

In the fuller App this excerpt derives from, there are 6 items to conditionally render in the sidebarpanel, not just one.

My attempts to show/hide the selectInput() box are commented as # ATTEMPT in the below reproducible code. The longish renderTable() function below can be safely ignored: I chose not reduce it as much as I could have to make this more MWE, since it is ignorable and will make any solution easier to stitch back into the fuller App.

The images at the bottom better explain what I am trying to do.

Reproducible code (I don't think library(shinyWidgets) is required, but just in case...):

library(shiny)
library(shinyjs)
library(tidyverse)

ui <-
  fluidPage(
    titlePanel("Test"),
    sidebarLayout(
      sidebarPanel(
        useShinyjs(), # ATTEMPT
        selectInput("selectView", h5(strong("Select view:")), 
                     choices = list("Summary","Strats"), 
                     selected = "Summary"),
        hidden(uiOutput("stratPeriod")) # ATTEMPT
      ), # close sidebar panel
      mainPanel(
        tabsetPanel(
          tabPanel("Data",
            conditionalPanel(
                condition = "input.selectView == 'Strats'",       
                h5(strong("Stratified data:")), tableOutput("stratData")
            ) # close conditional panel
          ) # close tab panel
        ) # close tabset panel
      ) # close main panel
    ) # close sidebar layout
  ) # close fluid page

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

  dat <- reactive({
    data.frame(
      ID = c(1,1,2,2,2,2,3,3,3,3),
      Period = c("2020-03", "2020-04", "2020-01", "2020-02", "2020-03", "2020-04", "2020-01", "2020-02", "2020-03", "2020-04"),
      Values_1 = c(-6, 26, 36, 46, 56, 86, 100, 10, 20, 30),
      Values_2 = c(-6, 13, 18, 46, 28, 43, 100, 10, 10, 30)
    )  
  })
  
  observeEvent(input$selectView == 'Strats',{shinyjs::show("stratPeriod")}) # ATTEMPT
  
  output$stratPeriod <- renderUI({
    chc <- unique(na.omit(dat()[[2]]))
    selectInput(inputId = "stratPeriod", 
                label = "Choose point-in-time:",
                choices = chc,
                selected = chc[1])
  })
  
  output$stratData <- renderTable({
    req(input$stratPeriod)
    filter_exp1 <- parse(text=paste0("Period",  "==", "'",input$stratPeriod, "'"))
    dat_1 <- reactive({dat() %>% filter(eval(filter_exp1))})
    min <- if (length(dat_1()[["Values_1"]])>0) min(dat_1()[["Values_1"]], na.rm=TRUE) else Inf
    max <- if (length(dat_1()[["Values_1"]])>0) max(dat_1()[["Values_1"]], na.rm=TRUE) else Inf
    breaks <- if(any(is.infinite(c(min,max)))) c(0, 10) else seq(min, max, length.out = 6) 
    tmp <- dat() %>% 
      filter(eval(filter_exp1)) %>%
      mutate(Range = cut(!!sym("Values_1"), breaks=breaks, include.lowest=TRUE, right = TRUE, dig.lab = 5)) %>% 
      group_by(Range) %>%
      summarise(Count = n(),Values = sum(!!sym("Values_1"))) %>%
      complete(Range, fill = list(Count = 0,Values = 0)) %>% 
      ungroup %>% 
      dplyr::select(everything(), Count, Values)
    tmp
  })

}

shinyApp(ui, server)

enter image description here

enter image description here



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source