0Pricing
R Academy · Pelajaran

UI Dinamis dengan renderUI dan insertUI

Buat elemen UI secara langsung berdasarkan input pengguna dan keadaan server.

UI Dinamis dengan renderUI dan insertUI adalah pelajaran R Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar R Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus R Academy mencakup 4 pelajaran total.

UI Dinamis — Mengapa dan Kapan

Terkadang UI yang Anda perlukan tidak dapat ditentukan sepenuhnya saat aplikasi dimulai — UI tersebut bergantung pada pilihan pengguna, data yang dimuat, atau kondisi saat runtime. Shiny menyediakan dua mekanisme: renderUI() untuk mengganti seluruh isi suatu tempat penampung, serta insertUI()/removeUI() untuk menambahkan atau menghapus elemen tanpa mengganti semuanya.

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() dan uiOutput()

renderUI({...}) di server membangun dan mengembalikan elemen UI secara reaktif. uiOutput('id') di UI membuat tempat penampung yang menampilkan apa pun yang dihasilkan renderUI. Seluruh isi tempat penampung diganti setiap kali proses reaktif dijalankan ulang.

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() dengan Beberapa Kontrol

Kembalikan tagList() dari renderUI() untuk merender beberapa elemen UI sekaligus. Ini adalah pola standar ketika jumlah kontrol bergantung pada data — misalnya membuat satu penyaring untuk setiap kolom dalam suatu kumpulan data.

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() — Menambahkan Elemen Secara Dinamis

insertUI(selector, where, ui) menyisipkan elemen UI ke dalam DOM tanpa membangun ulang seluruh halaman. Gunakan pemilih CSS untuk menentukan titik penyisipan. where dapat berupa 'afterEnd', 'beforeEnd', 'afterBegin', atau 'beforeBegin'.

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() — Menghapus Elemen

removeUI(selector) menghapus elemen DOM pertama yang cocok dengan pemilih CSS. Gunakan multiple = TRUE untuk menghapus semua elemen yang cocok. Fungsi ini melengkapi insertUI() untuk UI berbasis daftar, yang memungkinkan pengguna menambah dan menghapus item.

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() — Visibilitas di Sisi Klien

conditionalPanel(condition, ...) menampilkan atau menyembunyikan elemen UI berdasarkan kondisi JavaScript yang dievaluasi di peramban. Berbeda dengan renderUI(), elemen tersebut selalu berada di dalam DOM — hanya ditampilkan atau disembunyikan. Cara ini lebih cepat untuk logika tampil/sembunyi sederhana karena tidak memerlukan perjalanan bolak-balik ke server.

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() — Mengubah Masukan yang Ada

Alih-alih mengganti seluruh kontrol masukan, gunakan updateSelectInput(session, id, choices, selected) untuk hanya memperbarui pilihan atau nilai terpilih dari selectInput yang sudah ada. Fungsi pembaruan serupa tersedia untuk semua jenis masukan: updateSliderInput(), updateTextInput(), dan sebagainya.

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() dan updateNumericInput()

Fungsi pembaruan mengirim pesan ke peramban untuk mengubah nilai saat ini, nilai minimum, nilai maksimum, atau label dari masukan yang sudah ada. Cara ini lebih efisien daripada menghapus lalu membuat ulang kontrol dengan renderUI(), serta mempertahankan posisi kontrol dalam tata letak halaman.

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))
    )
  })
}

Mengakses Masukan renderUI dengan req()

Masukan yang dibuat secara dinamis dengan renderUI() bernilai NULL hingga dirender. Gunakan req(input$dynamic_input) dalam kode server apa pun yang bergantung pada masukan dinamis untuk mencegah kesalahan saat inisialisasi.

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]])
  })
}

Tab Dinamis dengan appendTab()

appendTab(inputId, tab, select) menambahkan tab baru ke tabsetPanel() saat runtime. removeTab(inputId, target) menghapus satu tab. Pola ini memungkinkan alur kerja yang membuat pengguna dapat membuka, menutup, dan berpindah di antara tampilan analisis yang dibuat secara dinamis.

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 vs insertUI — Kapan Menggunakan Masing-Masing

Pilih alat yang tepat berdasarkan kebutuhan Anda:

  • renderUI(): mengganti seluruh isi tempat penampung secara reaktif. Paling sesuai ketika seluruh blok berubah secara bersamaan.
  • insertUI(): menambahkan elemen baru ke isi yang sudah ada. Paling sesuai untuk daftar yang terus bertambah ketika Anda tidak ingin merender ulang semuanya.
  • updateXxxInput(): mengubah masukan yang sudah ada secara langsung. Paling sesuai untuk mengubah pilihan atau nilai tanpa merender ulang.
  • conditionalPanel(): menampilkan atau menyembunyikan elemen tanpa perjalanan bolak-balik ke server. Paling sesuai untuk logika visibilitas sederhana.
# 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)
}

Pemeriksaan Singkat

Apa perbedaan utama antara renderUI() dan insertUI() saat membangun UI dinamis di Shiny?

Rangkuman UI Dinamis

Hal-hal penting dari UI Dinamis dengan renderUI dan insertUI:

  • renderUI({}) + uiOutput('id'): mengganti seluruh isi tempat penampung secara reaktif.
  • Kembalikan tagList() dari renderUI() untuk merender beberapa elemen sekaligus.
  • insertUI(selector, where, ui): menyisipkan elemen ke lokasi DOM mana pun.
  • removeUI(selector): menghapus elemen berdasarkan pemilih CSS.
  • conditionalPanel(condition, ...): menampilkan atau menyembunyikan elemen di sisi klien tanpa server.
  • updateSelectInput(), updateSliderInput(): mengubah masukan yang sudah ada secara langsung.
  • Selalu gunakan req(input$dynamic_id) untuk menangani nilai NULL sebelum masukan dinamis dirender.
# 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]])
  })
}

Pertanyaan yang Sering Diajukan

Apakah pelajaran “UI Dinamis dengan renderUI dan insertUI” gratis?

Ya — teks lengkap “UI Dinamis dengan renderUI dan insertUI” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus R Academy, upgrade ke CoddyKit PRO. Kursus R Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “UI Dinamis dengan renderUI dan insertUI”?

Buat elemen UI secara langsung berdasarkan input pengguna dan keadaan server. Kamu berlatih R Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai R Academy?

Tidak diperlukan pengalaman sebelumnya. R Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “UI Dinamis dengan renderUI dan insertUI” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran R Academy ini?

Ya. Setiap pelajaran R Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Pendalaman Pemrograman Reaktif
  2. Modul Shiny untuk Penggunaan Ulang Kode
  3. UI Dinamis dengan renderUI dan insertUI
  4. Menerapkan Aplikasi Shiny
← Kembali ke R Academy