Search code examples
rshinyshinyjs

Shiny - reactive UI & inputs


I have a Shiny dashboard where I would like the tab to depend upon certain data and then the dropdown input to determine what output is presented (i.e. table, boxplot, line graph). I have 3 tabs and 3 output options, so there are essentially 9 different outputs altogether. I think I have to use shinyjs to show/hide content appropriately, but as this depends upon both the selected tab and input, I'm unsure how to do this. Here is code that hopefully demonstrates what I'm trying to do (obviously the commented out part does nothing and doesn't work but is intended to try and show what I am wanting to happen):

library(shiny)
ui <- fluidPage(
  sidebarLayout(position = "right",
  sidebarPanel(
    selectInput("select", label = h3("Select Output:"), 
                choices = list("Table" = 1, "Boxplot" = 2, "Line Graph" = 3), 
                selected = 1),
  ),
  mainPanel(
    tabsetPanel(id = "tabSwitch",
                tabPanel("Tab 1", br(), "Data A"),
                tabPanel("Tab 2", br(), "Data B"),
                tabPanel("Tab 3", br(), "Data C")
    ), 
  )
)
)
server <- function(input, output, session) {
  observeEvent(input$tabSwitch, {
    print(paste("You clicked tab:", input$tabSwitch))
  })
  # observeEvent(input$select, {
  #   if(input$select == 1 & input$tabSwitch == "Tab 1"){
  #     renderPrint("Table 1")
  #   } else if (input$select == 1 & input$tabSwitch == "Tab 2"){
  #     renderPrint("Table 2")
  #   } else if (input$select == 1 & input$tabSwitch == "Tab 3"){
  #     renderPrint("Table 3")
  #   } else if (input$select == 2 & input$tabSwitch == "Tab 1"){
  #     renderPrint("Boxplot 1")
  #   } else if (input$select == 2 & input$tabSwitch == "Tab 2"){
  #     renderPrint("Boxplot 2")
  #   } else if (input$select == 2 & input$tabSwitch == "Tab 3"){
  #     renderPrint("Boxplot 3")
  #   } else if (input$select == 3 & input$tabSwitch == "Tab 1"){
  #     renderPrint("LineGraph 1")
  #   } else if (input$select == 3 & input$tabSwitch == "Tab 2"){
  #     renderPrint("LineGraph 2")
  #   } else if (input$select == 3 & input$tabSwitch == "Tab 3"){
  #     renderPrint("LineGraph 3")
  #   }
  # })
}
shinyApp(ui, server)

Solution

  • Thanks @Limey, I think this was more simple than I initially thought. I think the uiOutput in each tabPanel will solve this appropriately as below:

    library(shiny)
    ui <- fluidPage(
      sidebarLayout(position = "right",
      sidebarPanel(
        selectInput("select", label = h3("Select Output:"), 
                    choices = list("Table" = 1, "Boxplot" = 2, "Line Graph" = 3), 
                    selected = 1),
      ),
      mainPanel(
        tabsetPanel(id = "tabSwitch",
                    tabPanel("Tab 1", br(), "Data A", uiOutput("DASSoutput")),
                    tabPanel("Tab 2", br(), "Data B", uiOutput("PWIoutput")),
                    tabPanel("Tab 3", br(), "Data C", uiOutput("TPSoutput"))
        ), 
      )
    )
    )
    server <- function(input, output, session) {
      observeEvent(input$tabSwitch, {
        print(paste("You clicked tab:", input$tabSwitch))
      })
      
      output$DASSoutput <- renderUI({
          if(input$select == 1){
            renderPrint("Table 1")
          } else if (input$select == 2){
            renderPrint("Boxplot 1")
          } else if (input$select == 3){
            renderPrint("Linegraph 1")
          }
      })
      
      output$PWIoutput <- renderUI({
        if(input$select == 1){
          renderPrint("Table 2")
        } else if (input$select == 2){
          renderPrint("Boxplot 2")
        } else if (input$select == 3){
          renderPrint("Linegraph 2")
        }
      })
      
      output$TPSoutput <- renderUI({
        if(input$select == 1){
          renderPrint("Table 3")
        } else if (input$select == 2){
          renderPrint("Boxplot 3")
        } else if (input$select == 3){
          renderPrint("Linegraph 3")
        }
      })
    }
    shinyApp(ui, server)