In my shiny app, I want to allow the user to select one subject and then display some information on that subject.
The information looks similar for each subject and is defined in a shiny module, subj_ui() / subj_srv()
. The user can select the subject using nav_menu/nav_panel
.
The current approach "instantiates" a module for each subject, like this:
subj_ui <- function(id) {
ns <- shiny::NS(id)
bslib::page(
bslib::value_box(
title = "Position",
value = shiny::textOutput(ns("pos")),
max_height = "200px",
width="25%"
)
)
}
subj_srv <- function(id) shiny::moduleServer(id, function(input, output, session) {
output$pos <- shiny::renderText(which(LETTERS==id))
})
ui <- bslib::page_navbar(
id="nav",
title="Static Menu",
selected="A",
bslib::nav_menu("Subject",
bslib::nav_panel(title="A", value="A", subj_ui("A")),
bslib::nav_panel(title="B", value="B", subj_ui("B")),
bslib::nav_panel(title="C", value="C", subj_ui("C"))
)
)
server <- function(input, output, session) {
subj_srv("A")
subj_srv("B")
subj_srv("C")
}
shiny::shinyApp(ui, server)
This creates a server module for each subject. However, in my app, the number of subjects is higher (around 20) and ui and server functions are more complex (involving database queries).
So I wonder if I can "instantiate" only one module and reuse it for all subjects?.
(When working with shinydashboard
, I could define menuItems that include the subject information (like "subj_A", observe input$tabs
and set a reactive to the subject and call updateTabItems
manually. Is there a similar route for bslib?)
Finally figured out a solution. Not very elegant, still interested in best practices.
Note that the
nav_panel_hidden
object is NOT inside anav_menu
. If it were, the menu would stay open when the user selects an menu item. See here for a discussion.