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

R Shiny中使用sortable.js为列表元素追加出现次数字母后缀

拖拽列表元素追加重复次数字母标识实现方案

需求说明

现有代码已实现两个面板间的元素拖拽功能,且通过CSS自动为「Drag to」面板内的拖入元素添加顺序数字编号,现需要在每个列表元素末尾追加该元素在「Drag to」列表中累计出现次数对应的字母标识(第1次出现加a、第2次加b,以此类推)。
效果示例图

原始可复现代码

library(shiny)
library(sortable)
library(htmlwidgets)

icons <- function(x) {lapply(x,function(x){tags$div(tags$strong(x))})}

ui <- fluidPage(
  
  tags$head(
    tags$style(HTML('
      #dragTo {list-style-type: none;  counter-reset: css-counter 0;}
      #dragTo > div {counter-increment: css-counter 1;}
      #dragTo > div:before {content: counter(css-counter) ". ";}
      ')
    )
  ),
  
  div(
    style = "margin-top: 2rem; width: 60%; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: start;",
    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag from here"),
        div(
          class = "panel-body",
          id = "dragFrom",
          icons(c("Puppies", "Kittens"))
        )
      ),
    ),
    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag to here"),
        div(
          class = "panel-body",
          id = "dragTo"
        )
      )
    )
  ),
  sortable_js(
    "dragFrom",
    options = sortable_options(
      group = list(
        pull = "clone",
        name = "group1",
        put = FALSE
      )
    )
  ),
  sortable_js(
    "dragTo",
    options = sortable_options(
      group = list(
        group = "group1",
        put = TRUE,
        pull = TRUE
      ),
      onSort = sortable_js_capture_input(input_id = "selected")
    )
  ),
  helpText(h5(strong("Output to table:"))),
  tableOutput("table1")
)

server <- function(input, output) {
  dragToLabels <- reactive({
    data.frame(data = paste0(seq_along(input$selected), ". ", input$selected))
  })
  
  output$table1 <- renderTable({dragToLabels()})
}

shinyApp(ui, server)

实现方法

核心修改逻辑:

  • 移除原有CSS自动生成数字前缀的规则,避免和动态生成的文本重复
  • 服务端监听拖拽后的元素列表,按元素值分组计算累计出现次数,匹配R内置letters向量得到对应字母后缀
  • 动态渲染「Drag to」面板内的元素内容,同步更新输出表格

修改后完整代码

library(shiny)
library(sortable)
library(htmlwidgets)

icons <- function(x) {lapply(x,function(x){tags$div(tags$strong(x))})}

ui <- fluidPage(
  
  tags$head(
    tags$style(HTML('
      #dragTo {list-style-type: none; padding-left: 0;}
      ')
    )
  ),
  
  div(
    style = "margin-top: 2rem; width: 60%; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: start;",
    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag from here"),
        div(
          class = "panel-body",
          id = "dragFrom",
          icons(c("Puppies", "Kittens"))
        )
      ),
    ),
    div(
      div(
        class = "panel panel-default",
        div(class = "panel-heading", "Drag to here"),
        div(
          class = "panel-body",
          id = "dragTo",
          uiOutput("dragToContent")
        )
      )
    )
  ),
  sortable_js(
    "dragFrom",
    options = sortable_options(
      group = list(
        pull = "clone",
        name = "group1",
        put = FALSE
      )
    )
  ),
  sortable_js(
    "dragTo",
    options = sortable_options(
      group = list(
        group = "group1",
        put = TRUE,
        pull = TRUE
      ),
      onSort = sortable_js_capture_input(input_id = "selected")
    )
  ),
  helpText(h5(strong("Output to table:"))),
  tableOutput("table1")
)

server <- function(input, output) {
  # 生成带序号、字母后缀的标签数据
  dragToLabels <- reactive({
    req(input$selected)
    # 按元素分组计算累计出现次数
    occur_seq <- as.integer(ave(seq_along(input$selected), input$selected, FUN = seq_along))
    suffix_letter <- letters[occur_seq]
    data.frame(
      data = paste0(seq_along(input$selected), ". ", input$selected, " ", suffix_letter)
    )
  })
  
  # 渲染拖拽面板内的元素
  output$dragToContent <- renderUI({
    req(dragToLabels())
    lapply(dragToLabels()$data, function(txt) tags$div(tags$strong(txt)))
  })
  
  # 渲染输出表格
  output$table1 <- renderTable({dragToLabels()})
}

shinyApp(ui, server)

效果说明

  • 拖入第1个Puppies,显示为1. Puppies a
  • 再拖入1个Kittens,显示为2. Kittens a
  • 再拖入1个Puppies,显示为3. Puppies b
  • 元素排序调整、删除时,序号和字母后缀会自动重新计算匹配

内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 04:27:26