Dynamic UI

Lecture 29

Dr. Eric Friedlander

College of Idaho
CSCI 2025 - Winter 2026

Updating Inputs

The update* Family

  • Goal: Change an input’s state (value, choices, label) from the server.
  • Functions: updateTextInput(), updateSliderInput(), updateSelectInput(), etc.
  • Mechanism:
    • User action triggers an observeEvent().
    • Server sends a message to the browser to update the specific control.
observeEvent(input$reset, {
  updateSliderInput(inputId = "s1", value = 0, session = session)
})

Hierarchical Selects

Consider this scenario from Chapter 9 of the textbook.

Create an app that lets the user upload a csv file, select one variable, draw a histogram, and then download the histogram. For an additional challenge, allow the user to select from .png, .pdf, and .svg output formats.

Dynamic Visibility

Hiding and Showing

  • Goal: Show different UI elements based on user actions.
  • Technique: Hidden Tabsets.
    • tabsetPanel(id = "wizard", type = "hidden", ...)
    • updateTabsetPanel(inputId = "wizard", selected = "panel2", session = session)
ui <- fluidPage(
  actionButton("go_next", "Next"),
  tabsetPanel(id = "wizard", type = "hidden",
    tabPanel("page1", "First step content..."),
    tabPanel("page2", "Second step content...")
  )
)

server <- function(input, output, session) {
  observeEvent(input$go_next, {
    updateTabsetPanel(inputId = "wizard", selected = "page2", session = session)
  })
}

Generative UI

uiOutput and renderUI

  • Goal: Generate HTML or Inputs entirely from Python/R code.
  • Usage:
    1. UI: Place uiOutput("id") where you want the content.
    2. Server: Assign renderUI({ ... }) to output$id.
    3. Return: The renderUI block must return Shiny tags (e.g., tagList, div, inputs).

Circular References

  • Warning: Be careful when creating inputs that trigger the same code that created them.
  • Loop: renderUI -> creates input -> input changes -> triggers renderUI -> re-creates input.
  • Rate limiting or logic checks are often needed.

Wrap Up

Levels of Dynamism

  1. Update: Modify existing inputs (update*Input).
  2. Visibility: Show/Hide pre-defined sections (tabsetPanel).
  3. Generation: Create new UI from scratch (uiOutput/renderUI).

Do Next

  1. Read Chapter 10: Dynamic UI from Mastering Shiny.
  2. There’s NO recitation Gem for this textbook but I recommend creating your own and adding the textbook chapter and these slides.
  3. I reommend working through the Exercises in the textbook.
  4. Move on to Lecture 30!