I'm currently working on a Shiny application that utilizes modules to create tables in different tabs. My intent is to render different datasets depending on the selected tab using one module to manage the DTOutput
. However, I'm encountering some challenges in dynamically calling and rendering the module based on the selected tab. Below is a simplified example:
library(shiny)
library(DT)
tableModuleUI <- function(id) {
ns <- NS(id)
DTOutput(ns("table"))
}
tableModule <- function(input, output, session, data) {
output$table <- renderDT({
data()
})
}
ui <- fluidPage(
tabsetPanel(
id = "tabModeTransport",
tabPanel("Mode A", tableModuleUI("modeA")),
tabPanel("Mode B", tableModuleUI("modeB"))
)
)
server <- function(input, output, session) {
datasets <- list(
modeA = mtcars,
modeB = iris
)
observeEvent(input$tabModeTransport, {
if (input$tabModeTransport == "modeA") {
callModule(tableModule, "modeA", reactive({datasets$modeA}))
}
else if (input$tabModeTransport == "modeB") {
callModule(tableModule, "modeB", reactive({datasets$modeB}))
}
})
}
shinyApp(ui = ui, server = server)
While the above code works in a basic scenario, it seems inefficient, especially when scaling with more tabs and modules, as it requires explicit conditional logic for each tab. I was expecting something more dynamic, where I can render the module for any selected tab without requiring explicit condition checking for each tab.
Here are my questions:
Is there a more efficient approach to manage module calling and rendering for different tabs?
Is it possible to dynamically choose which dataset/module to render based on the active tab without employing multiple conditional checks?
I appreciate any advice or insights into potential solutions or best practices!
You have to use the argument value
in tabPanel
. Here is the app including this correction as well as the code of my comment, to avoid the if/else
:
library(shiny)
library(DT)
tableModuleUI <- function(id) {
ns <- NS(id)
DTOutput(ns("table"))
}
tableModule <- function(input, output, session, data) {
output$table <- renderDT({
data()
})
}
ui <- fluidPage(
tabsetPanel(
id = "tabModeTransport",
tabPanel("Mode A", tableModuleUI("modeA"), value = "modeA"),
tabPanel("Mode B", tableModuleUI("modeB"), value = "modeB")
)
)
server <- function(input, output, session) {
datasets <- list(
modeA = mtcars,
modeB = iris
)
observeEvent(input$tabModeTransport, {
mode <- input$tabModeTransport
callModule(tableModule, mode, reactive(datasets[[mode]]))
})
}
shinyApp(ui = ui, server = server)