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
相关产品推荐
相关产品推荐

