如何让Shiny的SelectInput支持重复选项的多次选择?
解决Shiny selectInput允许多次选择同一选项的问题
要实现选中选项后不消失、允许多次选择同一选项的效果,核心思路是给每个同名选项分配唯一的底层值,同时动态维护下拉菜单的选项列表,确保每次选择后仍能继续选择原始的所有选项。
完整解决方案代码
library(shiny) ui <- fluidPage( selectInput( inputId = "ManyDuplicated", label = 'SelectInput', # 初始选项:给每个显示名称分配带唯一后缀的底层值 choices = setNames(c("Hello_1", "World_1"), c("Hello", "World")), selected = NULL, multiple = TRUE ) ) server <- function(input, output, session) { observeEvent(input$ManyDuplicated, { # 隔离当前选中值,避免触发循环更新 current_selected <- isolate(input$ManyDuplicated) # 从底层值中提取显示名称(去掉数字后缀) selected_labels <- sub("_\\d+$", "", current_selected) # 统计每个原始选项的已选次数 count_hello <- sum(selected_labels == "Hello") count_world <- sum(selected_labels == "World") # 生成新选项:每个原始选项保留「已选次数+1」个,确保还能继续选择 new_choices <- c( setNames(paste0("Hello_", 1:(count_hello + 1)), rep("Hello", count_hello + 1)), setNames(paste0("World_", 1:(count_world + 1)), rep("World", count_world + 1)) ) # 更新下拉菜单,保持当前选中的所有项 updateSelectInput(session, "ManyDuplicated", choices = new_choices, selected = current_selected) }, ignoreInit = TRUE) # 忽略初始化时的触发 } shinyApp(ui = ui, server = server)
方案说明
- 底层值用「名称_数字」格式区分同名选项,Shiny能识别为不同选项,但用户看到的始终是原始名称
- 每次用户选择后,动态计算每个选项的已选次数,生成「已选次数+1」个同名选项,保证可以继续选择该选项
- 使用
isolate()避免更新时触发循环,ignoreInit = TRUE防止初始化时执行更新逻辑
原问题信息
需求
允许用户多次选择同一个下拉选项,选中后该选项不会从菜单中移除。
最小可复现代码
library(shiny) ui <- fluidPage( selectInput( inputId = "ManyDuplicated", label = 'SelectInput', choices = c('Hello', 'World'), selected = NULL, multiple = TRUE ) ) server <- function(input, output) { } shinyApp(ui = ui, server = server)
当前效果

期望效果

已尝试方案(仅支持单个选项)
以下代码仅能适配单个选项的重复选择,无法支持多个选项:
library(shiny) ui <- fluidPage( selectInput("x", "choose", c("^" = 1), multiple = TRUE) ) server <- function(input, output, session) { observeEvent(input$x, { choices <- seq_len(length(input$x)+1) names(choices) <- rep("^", length(choices)) updateSelectInput(session, "x", choices = choices, selected = isolate(input$x)) }) } shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者Pedro Teles
相关产品推荐
相关产品推荐

