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

如何为shinyjqui的updateOrderInput传入多item_classes列表?

解决shinyjqui::updateOrderInput无法传入item_classes向量的问题

由于shinyjqui::updateOrderInput()原生不支持传入类向量给每个元素单独设置样式,我们可以通过两种方式实现需求:让元素"A"显示success类的绿色,其他元素用warning类的黄色。

方案1:手动用JavaScript为元素绑定对应样式类

借助shinyjs简化JS执行,在更新orderInput内容后,手动给每个列表项替换样式类:

library(shiny)
library(shinyjqui)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  orderInput("my_order", "Items", items = c("X", "Y"), item_class = "warning"),
  actionButton("load_suggest", "Load suggestion")
)

server <- function(input, output, session) {
  observeEvent(input$load_suggest, {
    # 定义新元素和对应的样式类
    target_items <- c("A", "B")
    target_classes <- c("success", "warning")
    
    # 先更新orderInput的元素内容
    updateOrderInput(session, "my_order", items = target_items, item_class = "warning")
    
    # 延迟执行JS,确保DOM已完成更新
    delay(100, {
      runjs(paste0(
        "$('#my_order').find('.ui-sortable-handle').each(function(idx) {
           $(this).removeClass('warning').addClass('", paste(target_classes, collapse="','"), "')[idx];
         });"
      ))
    })
  })
}

shinyApp(ui, server)

关键逻辑:

  • 先用updateOrderInput更新元素列表,这里的item_class只是临时占位
  • 用delay()确保页面元素更新完成后,再定位到每个可排序项,移除原有类并添加对应目标类
  • $('#my_order').find('.ui-sortable-handle')精准定位orderInput内的所有列表项,按索引匹配target_classes中的样式类

方案2:重写updateOrderInput函数,原生支持item_classes参数

如果需要长期使用这个功能,可以重写函数并添加前端绑定,让它直接支持传入类向量:

library(shiny)
library(shinyjqui)

# 重写updateOrderInput,新增item_classes参数
updateOrderInput <- function(session, inputId, items = NULL, item_class = NULL, item_classes = NULL, ...) {
  message <- dropNulls(list(
    items = items,
    item_class = item_class,
    item_classes = item_classes,
    ...
  ))
  session$sendInputMessage(inputId, message)
}

# 自定义前端逻辑,处理item_classes消息
custom_binding <- HTML('
<script>
$(document).on("shiny:inputmessage", function(event) {
  const input = $("#" + event.targetId);
  const msg = event.message;
  // 当消息包含item_classes且有对应元素时,批量设置样式类
  if (msg.item_classes && msg.items && input.hasClass("jqui-order-input")) {
    input.find(".ui-sortable-handle").each(function(idx) {
      $(this).removeClass("success warning info danger").addClass(msg.item_classes[idx]);
    });
  }
});
</script>
')

ui <- fluidPage(
  custom_binding,
  orderInput("my_order", "Items", items = c("X", "Y"), item_class = "warning"),
  actionButton("load_suggest", "Load suggestion")
)

server <- function(input, output, session) {
  observeEvent(input$load_suggest, {
    updateOrderInput(
      session, "my_order", 
      items = c("A", "B"), 
      item_classes = c("success", "warning") # 直接传入类向量
    )
  })
}

shinyApp(ui, server)

关键逻辑:

  • 重写的updateOrderInput函数新增item_classes参数,并将其包含在发送给前端的消息中
  • 前端监听shiny:inputmessage事件,当收到包含item_classes的消息时,按索引为每个列表项设置对应样式类
  • 先移除所有可能的Bootstrap状态类,避免样式叠加冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:10:18