Conditional panels within shiny modules

R
shiny
TIL
Author

Thomas Sandmann

Published

April 7, 2024

tl;dr

The shiny R package includes the conditionalPanel function to show / hide a panel depending on a javascript expression. Today I learned how to use a conditionalPanel within a shiny module.

A shiny module with several conditional selectors

The following example 1 expands the example shown on the conditionalPanel help page.

It encapsulates the ui and server elements in separate functions, that together constitute the mod_histogram module.

library(shiny)

mod_histogram_ui <- function(id){
1    ns <- NS(id)
    fluidPage(
      sidebarPanel(
        selectInput(ns("plotType"), "Plot Type",
                    c(Scatter = "scatter", Histogram = "hist")
        ),
        # Only show this panel if the plot type is a histogram
        conditionalPanel(
          condition = "input.plotType == 'hist'",
2          ns = ns,
          selectInput(
            ns("breaks"), "Breaks",
            c("Sturges", "Scott", "Freedman-Diaconis", "[Custom]" = "custom")
          ),
          # Only show this panel if Custom is selected
          conditionalPanel(
            condition = "input.breaks == 'custom'",
            ns = ns,
            sliderInput(ns("breakCount"), "Break Count", min = 1,
                        max = 100, value = 10)
          )
        )
      ),
      mainPanel(
        plotOutput(ns("plot"))
      )
    )
}

mod_histogram_server <- function(id, df, labels, interactive = FALSE){
  moduleServer( id, function(input, output, session){
    x <- rnorm(1000)
    y <- rnorm(1000)

    output$plot <- renderPlot({
      if (input$plotType == "scatter") {
        plot(x, y)
      } else {
        breaks <- input$breaks
        if (breaks == "custom") {
          breaks <- input$breakCount
        }
        hist(x, breaks = breaks)
      }
    })
  })
}

histogramApp <- function() {
  ui <- mod_histogram_ui("histogram_1")
  server <- function(input, output, session) {
    mod_histogram_server("histogram_1")
  }

  shinyApp(ui, server)
}
1
The ns object defined in the UI part of the module takes care of managing the module’s namespace.
2
The ns namespace is passed as an argument to each conditionalPanel call. It automatically modifies the condition javascript expression, so we do not need to include the module’s id ourselves (e.g. via paste or sprintf, as is sometimes advised on Stack Overflow).

To see a minial shiny app, call the histogramApp() function:

histogramApp()

Reproducibility

Session Information
sessioninfo::session_info("attached")
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.3.2 (2023-10-31)
 os       Debian GNU/Linux 12 (bookworm)
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/Los_Angeles
 date     2024-04-07
 pandoc   3.1.1 @ /usr/lib/rstudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)

─ Packages ───────────────────────────────────────────────────────────────────
 ! package * version date (UTC) lib source
 P shiny   * 1.7.5   2023-08-12 [?] CRAN (R 4.3.1)

 [1] /home/sandmann/repositories/blog/renv/library/R-4.3/x86_64-pc-linux-gnu
 [2] /home/sandmann/.cache/R/renv/sandbox/R-4.3/x86_64-pc-linux-gnu/9a444a72

 P ── Loaded and on-disk path mismatch.

──────────────────────────────────────────────────────────────────────────────

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.

Footnotes

  1. Also available in this gist↩︎