Interface dynamique avec renderUI et insertUI
Générez des éléments d’interface à la volée selon les entrées de l’utilisateur et l’état du serveur.
Interface dynamique avec renderUI et insertUI est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.
Interface dynamique — Pourquoi et quand l’utiliser
Parfois, l’interface nécessaire ne peut pas être entièrement déterminée au démarrage de l’application : elle dépend des choix de l’utilisateur, des données chargées ou des conditions d’exécution. Shiny fournit deux mécanismes : renderUI() pour remplacer tout le contenu d’un espace réservé, et insertUI()/removeUI() pour ajouter ou supprimer des éléments sans tout remplacer.
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() et uiOutput()
renderUI({...}) construit et renvoie réactivement un élément d’interface dans le serveur. uiOutput('id') crée dans l’interface un espace réservé qui affiche ce que produit renderUI. L’intégralité du contenu de l’espace réservé est remplacée à chaque réexécution du réactif.
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() avec plusieurs contrôles
Renvoyez un tagList() depuis renderUI() pour afficher plusieurs éléments d’interface en une seule fois. Il s’agit du modèle standard lorsque le nombre de contrôles dépend des données, par exemple pour générer un filtre par colonne d’un jeu de données.
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() — Ajouter des éléments dynamiquement
insertUI(selector, where, ui) insère un élément d’interface dans le DOM sans reconstruire toute la page. Utilisez des sélecteurs CSS pour cibler le point d’insertion. where peut être 'afterEnd', 'beforeEnd', 'afterBegin' ou '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() — Supprimer des éléments
removeUI(selector) supprime le premier élément du DOM correspondant au sélecteur CSS. Utilisez multiple = TRUE pour supprimer tous les éléments correspondants. C’est le complément de insertUI() pour les interfaces fondées sur des listes, dans lesquelles les utilisateurs peuvent ajouter et supprimer des éléments.
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() — Visibilité côté client
conditionalPanel(condition, ...) affiche ou masque des éléments d’interface selon une condition JavaScript évaluée dans le navigateur. Contrairement à renderUI(), les éléments sont toujours présents dans le DOM : ils sont simplement visibles ou masqués. Cette solution est plus rapide pour une logique simple d’affichage et de masquage, car elle ne nécessite aucun aller-retour avec le serveur.
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() — Modifier des entrées existantes
Au lieu de remplacer tout un contrôle d’entrée, utilisez updateSelectInput(session, id, choices, selected) pour mettre à jour uniquement les choix ou la valeur sélectionnée d’un selectInput existant. Des fonctions de mise à jour similaires existent pour tous les types d’entrées : updateSliderInput(), updateTextInput(), etc.
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() et updateNumericInput()
Les fonctions de mise à jour envoient un message au navigateur pour modifier la valeur actuelle, le minimum, le maximum ou le libellé d’une entrée existante. Cette approche est plus efficace que la suppression et la recréation du contrôle avec renderUI(), et elle conserve sa position dans la mise en page.
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))
)
})
}Accéder aux entrées de renderUI avec req()
Les entrées créées dynamiquement avec renderUI() valent NULL tant qu’elles n’ont pas été affichées. Utilisez req(input$dynamic_input) dans tout code serveur qui dépend d’entrées créées dynamiquement afin d’éviter les erreurs lors de l’initialisation.
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]])
})
}Onglets dynamiques avec appendTab()
appendTab(inputId, tab, select) ajoute un nouvel onglet à un tabsetPanel() au moment de l’exécution. removeTab(inputId, target) en supprime un. Ce modèle permet de créer des flux de travail dans lesquels les utilisateurs ouvrent, ferment et parcourent des vues d’analyse générées dynamiquement.
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 ou insertUI — Quand utiliser chaque fonction
Choisissez l’outil adapté à votre besoin :
- renderUI() : remplacer réactivement tout le contenu d’un espace réservé. Idéal lorsque tout le bloc change en même temps.
- insertUI() : ajouter de nouveaux éléments à un contenu existant. Idéal pour les listes qui s’agrandissent lorsque vous ne voulez pas tout réafficher.
- updateXxxInput() : modifier une entrée existante sur place. Idéal pour changer les choix ou les valeurs sans effectuer de nouveau rendu.
- conditionalPanel() : afficher ou masquer sans aller-retour avec le serveur. Idéal pour une logique simple de visibilité.
# 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)
}Vérification rapide
Quelle est la différence essentielle entre renderUI() et insertUI() pour construire une interface dynamique dans Shiny ?
Récapitulatif des interfaces dynamiques
Points essentiels des interfaces dynamiques avec renderUI et insertUI :
renderUI({}) + uiOutput('id'): remplacer réactivement tout le contenu d’un espace réservé.- Renvoyez
tagList()depuisrenderUI()pour afficher plusieurs éléments en une seule fois. insertUI(selector, where, ui): injecter des éléments à n’importe quel emplacement du DOM.removeUI(selector): supprimer des éléments à l’aide d’un sélecteur CSS.conditionalPanel(condition, ...): afficher ou masquer côté client sans intervention du serveur.updateSelectInput(),updateSliderInput(): modifier des entrées existantes sur place.- Utilisez toujours
req(input$dynamic_id)pour vérifier que la valeur n’est pas NULL avant l’affichage des entrées dynamiques.
# 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]])
})
}Questions Fréquemment Posées
La leçon « Interface dynamique avec renderUI et insertUI » est-elle gratuite ?
Oui — le texte complet de « Interface dynamique avec renderUI et insertUI » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Interface dynamique avec renderUI et insertUI » ?
Générez des éléments d’interface à la volée selon les entrées de l’utilisateur et l’état du serveur. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer R Academy ?
Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Interface dynamique avec renderUI et insertUI » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon R Academy ?
Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Approfondissement de la programmation réactive
- Modules Shiny pour réutiliser le code
- Interface dynamique avec renderUI et insertUI
- Déployer des applications Shiny