You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny R实现两个互斥selectizeInput选择菜单的开发问题求助

实现逻辑说明
  • 核心逻辑为监听两个多选菜单的选中值变化,每次其中一个菜单的选中值更新时,过滤掉另一个菜单已选值中与当前菜单选中值重叠的部分,再通过updateSelectizeInput更新另一个菜单的选中状态
  • 模块服务端内调用updateSelectizeInput时不需要额外加命名空间(ns),直接传入原生输入id即可,模块的session对象会自动处理命名空间匹配
完整可运行最小示例(MWE)
library(shiny)
library(shinyjs)
library(shinyalert)

# 模块UI
mod_saving_side_ui <- function(id){
  ns <- NS(id)
  tagList(
    shinyjs::useShinyjs(),
    shinyalert::useShinyalert(),
    uiOutput(outputId = ns("positive_markers")),
    uiOutput(outputId = ns("negative_markers"))
  )
}

# 模块服务端
mod_saving_side_server <- function(id, r){
  moduleServer( id, function(input, output, session){
    ns <- session$ns
 
    output$positive_markers <- renderUI({
      selectizeInput(inputId = ns("pos_markers"), label = "Positive:",
                     choices = LETTERS,
                     selected = LETTERS[1],
                     multiple = TRUE)
    })
 
    output$negative_markers <- renderUI({
      selectizeInput(inputId = ns("neg_markers"), label = "Negative:",
                     choices = LETTERS,
                     selected = LETTERS[2],
                     multiple = TRUE)
    })

    # 监听正向选中变化,更新负向选中列表
    observeEvent(input$pos_markers, {
      r$pos_markers <- input$pos_markers
      # 移除负向列表中与正向重叠的选中项
      new_neg_selected <- setdiff(input$neg_markers, input$pos_markers)
      updateSelectizeInput(session, inputId = "neg_markers", selected = new_neg_selected)
    }, ignoreInit = TRUE)

    # 监听负向选中变化,更新正向选中列表
    observeEvent(input$neg_markers , {
      r$neg_markers <- input$neg_markers
      # 移除正向列表中与负向重叠的选中项
      new_pos_selected <- setdiff(input$pos_markers, input$neg_markers)
      updateSelectizeInput(session, inputId = "pos_markers", selected = new_pos_selected)
    }, ignoreInit = TRUE)
    
  })
}

# 主应用UI
ui <- fluidPage(
  mod_saving_side_ui("saving_module")
)

# 主应用服务端
server <- function(input, output, session) {
  # 全局响应式变量存储选中结果
  r <- reactiveValues(
    pos_markers = NULL,
    neg_markers = NULL
  )
  # 调用模块
  mod_saving_side_server("saving_module", r)
  
  # 可选:打印选中结果到控制台验证
  observe({
    print(paste0("正向选中:", paste(r$pos_markers, collapse = ", ")))
    print(paste0("负向选中:", paste(r$neg_markers, collapse = ", ")))
  })
}

# 启动应用
shinyApp(ui, server)
关键修改说明
  • 使用setdiff()函数求两个选中列表的差集,仅删除重叠的互斥选项,保留两个菜单各自非重叠的原有选中项,符合多选场景的使用习惯
  • 保留了两个菜单完全相同的可选选项池,仅修改选中状态,匹配需求要求
  • 新增ignoreInit = TRUE参数避免应用启动时重复触发更新,如果需要启动时自动校正初始重叠的选中值,删除该参数即可
  • 补充了主应用的调用代码,你可以直接复制整段代码运行验证效果

内容的提问来源于stack exchange,提问作者DaniCee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:36:06