Home > Software engineering >  How to filters across multiple tabs R Shiny
How to filters across multiple tabs R Shiny

Time:08-31

I'm creating a R Shiny App that contains three tabs. I would like to display a filter on the first two tabs and no filter on the third tab. I would like the filter on tabs one and two to be synchronized.

library(shiny)

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

   dataset <- reactive({
      get(input$dataset, "package:datasets")
   })
   
   output$summary <- renderPrint({
      summary(dataset())
   })
   
   output$table <- renderTable({
      dataset()
   })
   
   output$table_head <- renderTable({
      head(dataset())
   })
}


ui <- fluidPage(

   tabsetPanel(type = "tabs",
               tabPanel(title = "tab one filtered",
                        sidebarLayout(
                           sidebarPanel(
                              selectInput("dataset", label = "filter", choices = ls("package:datasets"))
                              ),
                           mainPanel(
                           verbatimTextOutput("summary")
                           )
                        )
                     ),
               tabPanel(title = "tab two filtered",
                        sidebarLayout(
                           sidebarPanel(
                              selectInput("dataset", label = "filter", choices = ls("package:datasets"))
                              ),
                        mainPanel(
                           tableOutput("table")
                           )
                        )
                     ),
               tabPanel(title = "tab three unfiltered",
                        mainPanel(
                           tableOutput("table_head")
                        )
                     )
            )
)

shinyApp(ui, server)

My code is very similar to this. When I run this, the filter on the second page does not work. How can I display a synchronized filter on the first two tabs and no filter on the third tab. I've seen the suggestion to have the selectInput outside of the tabsetPanel but the filter will show on the third page. Thanks for the help.

CodePudding user response:

You can't have two elements with the same ID in a given layout. So first you'll want to given them separate IDs

tabPanel(title = "tab one filtered",
         sidebarLayout(
           sidebarPanel(
             selectInput("dataset1", label = "filter", choices = ls("package:datasets"))
           ),
           mainPanel(
             verbatimTextOutput("summary")
           )
         )
),
tabPanel(title = "tab two filtered",
         sidebarLayout(
           sidebarPanel(
             selectInput("dataset2", label = "filter", choices = ls("package:datasets"))
           ),
           mainPanel(
             tableOutput("table")
           )
         )
),

then you'll need to do some extra work in the server to keep them insync.

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

  datasetname <- reactiveVal(ls("package:datasets")[1])

  observeEvent(input$dataset1, {
    updateSelectInput(session, "dataset2", selected=input$dataset1)
    datasetname(input$dataset1)
  })
  observeEvent(input$dataset2, {
    updateSelectInput(session, "dataset1", selected=input$dataset2)
    datasetname(input$dataset2)
  })
  
  
  dataset <- reactive({
    get(datasetname(), "package:datasets")
  })
  ...
}

We keep a separate reactive value datasetname to keep track of the active name. Then we update the UI when one of the two dataset1/dataset2 values changes.

  • Related