Search code examples
rbslib

Make bslib::card_header dynamic


I am building a shiny server module. The UI part is a bslib::card(), like this:

my_mod_ui <- function(id) {
    ns <- shiny::NS(id)
    bslib::card(
        id=id,
        full_screen = TRUE, 

        # the following does not work properly:
        bslib::card_header(paste("Selected: ", shiny::textOutput(ns("selected")))), 

        bslib::layout_sidebar(
            sidebar = bslib::sidebar(
                selectInput(ns("choice"), choices=letters(1:5))
            ), 
            "Main contents"
        )
    )
}

The server part in this minimal example does simply update the selected output variable:

my_mod_srv <- function(id) 
    shiny::moduleServer(id, function(input, output, session) {  
        output$selected <- renderText(input$choice)
})

This code does not work, as the following app shows:

ui <- bslib::page_navbar(
    bslib::nav_panel("Test", my_mod_ui("id1"))
)

server <- function(input, output, session) {
    my_mod_srv("id1")
}

shinyApp(ui, server)

The problem seems to be that output$selected is rendered to an HTML element <div id="id1-selected" class="shiny-text-output"></div>.

How can I make the card header dynamic?

(note that I am using the github version of bslib, the CRAN version does not have a card yet.)


Solution

  • One option would be to move the paste part into renderText:

    Note: Assuming that output$wz_title is what you mean by output$selected.

    library(bslib)
    library(shiny)
    
    my_mod_ui <- function(id) {
      ns <- shiny::NS(id)
      bslib::card(
        id = id,
        full_screen = TRUE,
        bslib::card_header(shiny::textOutput(ns("selected"))),
        bslib::layout_sidebar(
          sidebar = bslib::sidebar(
            selectInput(ns("choice"), "", choices = letters[1:5])
          ),
          "Main contents"
        )
      )
    }
    
    my_mod_srv <- function(id) {
      shiny::moduleServer(id, function(input, output, session) {
        output$selected <- renderText(
          paste("Selected: ", input$choice)
        )
      })
    }
    
    ui <- bslib::page_navbar(
      bslib::nav_panel("Test", my_mod_ui("id1"))
    )
    
    server <- function(input, output, session) {
      my_mod_srv("id1")
    }
    
    shinyApp(ui, server)
    

    enter image description here