0Pricing
R Academy · Lektion

Dynamische UI mit renderUI und insertUI

Erzeugen Sie UI-Elemente dynamisch anhand von Benutzereingaben und dem Serverstatus

Dynamische UI mit renderUI und insertUI ist eine kostenlose R Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des R Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.

Dynamische UI — Warum und wann

Manchmal kann die benötigte UI beim Start der App noch nicht vollständig bestimmt werden — sie hängt von Benutzerauswahlen, geladenen Daten oder Bedingungen zur Laufzeit ab. Shiny stellt dafür zwei Mechanismen bereit: renderUI() zum Ersetzen des gesamten Inhalts eines Platzhalters sowie insertUI()/removeUI() zum Hinzufügen oder Entfernen von Elementen, ohne alles zu ersetzen.

library(shiny)

# Static UI: columns always shown
# ui <- fluidPage(selectInput('x', ...), selectInput('y', ...))

# Dynamic UI: columns depend on which dataset was loaded
# ui <- fluidPage(fileInput('upload', ...), uiOutput('var_selectors'))

renderUI() und uiOutput()

renderUI({...}) erstellt und gibt im Server reaktiv ein UI-Element zurück. uiOutput('id') erstellt in der UI einen Platzhalter, der anzeigt, was renderUI erzeugt. Der gesamte Inhalt des Platzhalters wird bei jeder erneuten Ausführung der Reaktivität ersetzt.

ui <- fluidPage(
  selectInput('dataset', 'Dataset:', choices = c('iris', 'mtcars')),
  uiOutput('column_selector')   # placeholder
)

server <- function(input, output, session) {
  output$column_selector <- renderUI({
    df <- get(input$dataset)  # reactive dependency on dataset
    selectInput('col', 'Choose Column:',
                choices = names(df))
  })
}

shinyApp(ui, server)

renderUI() mit mehreren Steuerelementen

Geben Sie aus renderUI() eine tagList() zurück, um mehrere UI-Elemente gleichzeitig zu rendern. Dies ist das übliche Muster, wenn die Anzahl der Steuerelemente von den Daten abhängt — beispielsweise beim Erzeugen eines Filters für jede Spalte eines Datensatzes.

server <- function(input, output, session) {
  output$filters <- renderUI({
    df    <- get(input$dataset)
    nums  <- names(df)[sapply(df, is.numeric)]

    # One slider per numeric column
    sliders <- lapply(nums, function(col) {
      rng <- range(df[[col]], na.rm = TRUE)
      sliderInput(
        inputId = paste0('filter_', col),
        label   = col,
        min     = rng[1], max = rng[2],
        value   = rng
      )
    })
    tagList(sliders)   # render all sliders
  })
}

insertUI() — Elemente dynamisch hinzufügen

insertUI(selector, where, ui) fügt ein UI-Element in das DOM ein, ohne die gesamte Seite neu aufzubauen. Verwenden Sie CSS-Selektoren, um die Einfügestelle festzulegen. Für where sind 'afterEnd', 'beforeEnd', 'afterBegin' oder 'beforeBegin' möglich.

server <- function(input, output, session) {
  item_count <- reactiveVal(0)

  observeEvent(input$add_item, {
    item_count(item_count() + 1)
    id <- paste0('item_', item_count())

    insertUI(
      selector = '#item_container',  # CSS selector
      where    = 'beforeEnd',
      ui       = div(
        id    = id,
        style = 'padding: 5px; border: 1px solid #ccc; margin: 3px;',
        textInput(id, paste('Item', item_count()), value = '')
      )
    )
  })
}

removeUI() — Elemente löschen

removeUI(selector) entfernt das erste DOM-Element, das dem CSS-Selektor entspricht. Verwenden Sie multiple = TRUE, um alle passenden Elemente zu entfernen. Dies ist das Gegenstück zu insertUI() für listenbasierte UIs, in denen Benutzerinnen und Benutzer Elemente hinzufügen und entfernen können.

server <- function(input, output, session) {
  observeEvent(input$remove_last, {
    # Remove the last item div
    n <- isolate(item_count())
    if (n > 0) {
      removeUI(selector = paste0('#item_', n))
      item_count(n - 1)
    }
  })

  observeEvent(input$clear_all, {
    # Remove all items matching a class
    removeUI(selector = '.dynamic-item', multiple = TRUE)
    item_count(0)
  })
}

conditionalPanel() — Sichtbarkeit auf der Clientseite

conditionalPanel(condition, ...) zeigt UI-Elemente an oder blendet sie aus, basierend auf einer JavaScript-Bedingung, die im Browser ausgewertet wird. Anders als bei renderUI() befinden sich die Elemente immer im DOM — sie sind lediglich sichtbar oder verborgen. Für einfache Anzeigen-/Ausblenden-Logik ist dies schneller, da keine Server-Roundtrips erforderlich sind.

ui <- fluidPage(
  selectInput('plot_type', 'Plot Type:',
              choices = c('scatter', 'histogram', 'boxplot')),

  # Only shown when scatter is selected
  conditionalPanel(
    condition = "input.plot_type == 'scatter'",
    selectInput('x_var', 'X Variable:', choices = names(mtcars)),
    selectInput('y_var', 'Y Variable:', choices = names(mtcars))
  ),

  # Only shown when histogram is selected
  conditionalPanel(
    condition = "input.plot_type == 'histogram'",
    sliderInput('bins', 'Number of bins:', 5, 50, 20)
  ),

  plotOutput('main_plot')
)

updateSelectInput() — Vorhandene Eingaben ändern

Statt ein vollständiges Eingabesteuerelement zu ersetzen, verwenden Sie updateSelectInput(session, id, choices, selected), um nur die Auswahlmöglichkeiten oder den ausgewählten Wert eines vorhandenen selectInput zu aktualisieren. Für alle Eingabetypen gibt es ähnliche Aktualisierungsfunktionen, etwa updateSliderInput() und updateTextInput().

server <- function(input, output, session) {
  # When dataset changes, update the column selector
  observeEvent(input$dataset, {
    df <- get(input$dataset)
    updateSelectInput(
      session  = session,
      inputId  = 'column',
      choices  = names(df),
      selected = names(df)[1]
    )
  })

  # Reset slider when reset button pressed
  observeEvent(input$reset_btn, {
    updateSliderInput(session, 'n_items',
                     value = 20, min = 1, max = 100)
  })
}

updateSliderInput() und updateNumericInput()

Aktualisierungsfunktionen senden eine Nachricht an den Browser, um den aktuellen Wert, das Minimum, das Maximum oder die Beschriftung einer vorhandenen Eingabe zu ändern. Das ist effizienter, als das Steuerelement mit renderUI() zu löschen und neu zu erstellen, und erhält seine Position im Seitenlayout.

server <- function(input, output, session) {
  # When data loads, set slider max to actual data length
  observeEvent(input$load_data, {
    data <- readRDS(input$upload$datapath)

    updateSliderInput(session, 'row_slider',
      min   = 1,
      max   = nrow(data),
      value = c(1, min(50, nrow(data)))
    )

    updateNumericInput(session, 'page_size',
      max   = nrow(data),
      value = min(10, nrow(data))
    )
  })
}

Auf renderUI-Eingaben mit req() zugreifen

Eingaben, die mit renderUI() dynamisch erstellt werden, sind bis zu ihrer Darstellung NULL. Verwenden Sie in jedem Servercode, der von dynamisch erstellten Eingaben abhängt, req(input$dynamic_input), um Fehler während der Initialisierung zu verhindern.

server <- function(input, output, session) {
  # dynamic input: 'col' is created by renderUI
  output$column_selector <- renderUI({
    selectInput('col', 'Column:', choices = names(get(input$dataset)))
  })

  output$summary_stats <- renderPrint({
    req(input$col)           # wait until 'col' exists
    req(input$dataset)       # and dataset is chosen
    df <- get(input$dataset)
    summary(df[[input$col]])
  })
}

Dynamische Tabs mit appendTab()

appendTab(inputId, tab, select) fügt zur Laufzeit einen neuen Tab zu einem tabsetPanel() hinzu. removeTab(inputId, target) entfernt einen Tab. Dieses Muster ermöglicht Arbeitsabläufe, in denen Benutzerinnen und Benutzer dynamisch erzeugte Analyseansichten öffnen, schließen und zwischen ihnen wechseln.

ui <- fluidPage(
  actionButton('add_tab', 'Open New Analysis Tab'),
  tabsetPanel(id = 'analysis_tabs', type = 'tabs')
)

server <- function(input, output, session) {
  tab_count <- reactiveVal(0)

  observeEvent(input$add_tab, {
    tab_count(tab_count() + 1)
    n <- tab_count()
    appendTab(
      inputId = 'analysis_tabs',
      select  = TRUE,
      tab = tabPanel(
        title = paste('Analysis', n),
        value = paste0('tab_', n),
        plotOutput(paste0('plot_', n)),
        actionButton(paste0('close_', n), 'Close')
      )
    )
  })
}

renderUI im Vergleich zu insertUI — Wann welches verwenden

Wählen Sie das passende Werkzeug für Ihren Anwendungsfall:

  • renderUI(): Den gesamten Inhalt eines Platzhalters reaktiv ersetzen. Am besten geeignet, wenn sich der gesamte Block gemeinsam ändert.
  • insertUI(): Neue Elemente zu vorhandenem Inhalt hinzufügen. Am besten geeignet für wachsende Listen, bei denen nicht alles neu gerendert werden soll.
  • updateXxxInput(): Eine vorhandene Eingabe direkt ändern. Am besten geeignet, um Auswahlmöglichkeiten oder Werte ohne erneutes Rendern zu ändern.
  • conditionalPanel(): Ohne Server-Roundtrip anzeigen oder ausblenden. Am besten geeignet für einfache Sichtbarkeitslogik.
# Decision guide:
# - 'Show filter only when advanced mode' -> conditionalPanel
# - 'Populate column choices from loaded CSV' -> updateSelectInput
# - 'Show different controls per selected tab' -> renderUI
# - 'Add a row editor for each row user adds' -> insertUI
# - 'Remove a row editor' -> removeUI

# Combining strategies:
server <- function(input, output, session) {
  # Use renderUI for column selectors (replaces whole block)
  output$col_selectors <- renderUI({ ... })
  # Use insertUI for dynamically added rows
  observeEvent(input$add_row, { insertUI(...) })
  # Use conditionalPanel for show/hide (in UI, no server code)
}

Kurztest

Was ist der wesentliche Unterschied zwischen renderUI() und insertUI() beim Erstellen einer dynamischen UI in Shiny?

Rückblick auf dynamische UI

Die wichtigsten Erkenntnisse aus „Dynamic UI with renderUI and insertUI“:

  • renderUI({}) + uiOutput('id'): den gesamten Inhalt eines Platzhalters reaktiv ersetzen.
  • Aus renderUI() eine tagList() zurückgeben, um mehrere Elemente gleichzeitig zu rendern.
  • insertUI(selector, where, ui): Elemente an jeder Stelle im DOM einfügen.
  • removeUI(selector): Elemente anhand eines CSS-Selektors entfernen.
  • conditionalPanel(condition, ...): Anzeigen oder Ausblenden auf der Clientseite ohne Server.
  • updateSelectInput(), updateSliderInput(): vorhandene Eingaben direkt ändern.
  • Verwenden Sie immer req(input$dynamic_id), um vor dem Rendern dynamischer Eingaben gegen NULL abzusichern.
# Typical pattern: dynamic column selector
ui <- fluidPage(
  fileInput('upload', 'Upload CSV'),
  uiOutput('col_ui'),          # placeholder
  plotOutput('col_plot')
)

server <- function(input, output, session) {
  df <- reactive({
    req(input$upload)
    read.csv(input$upload$datapath)
  })

  output$col_ui <- renderUI({
    req(df())
    selectInput('col', 'Column:', choices = names(df()))
  })

  output$col_plot <- renderPlot({
    req(input$col)
    hist(df()[[input$col]])
  })
}

Häufig gestellte Fragen

Ist die Lektion „Dynamische UI mit renderUI und insertUI“ kostenlos?

Ja — der vollständige Text von „Dynamische UI mit renderUI und insertUI“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des R Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Dynamische UI mit renderUI und insertUI“?

Erzeugen Sie UI-Elemente dynamisch anhand von Benutzereingaben und dem Serverstatus Du übst R Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um R Academy zu starten?

Keine Vorkenntnisse erforderlich. R Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Dynamische UI mit renderUI und insertUI“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser R Academy-Lektion Code schreiben und ausführen?

Ja. Jede R Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Reaktive Programmierung im Detail
  2. Shiny-Module zur Codewiederverwendung
  3. Dynamische UI mit renderUI und insertUI
  4. Shiny-Apps bereitstellen
← Zurück zu R Academy