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

使用shinyjqui实现网格表格拖拽功能遇阻求助

解决shinyjqui中orderInput拖拽至自定义网格表格失效问题

我在测试shinyjqui包时,发现orderInput()函数可通过connect参数实现拖拽功能,但尝试将元素拖拽到自定义网格表格时无法正常工作。以下是我编写的代码:

library(shiny)
library(shinyjqui)

connections <- c('my_grid') # 网格表格的id

ui <- fluidPage(
  # 样式设置
  tags$head(
    tags$style(HTML(".grid-table {\n        width: 150px;\n        border-collapse: collapse;\n      }\n      .grid-cell {\n        width: 100%;\n        height: 50px;\n        border: 1px solid black;\n        background-color: white;\n        text-align: center;\n        margin: 0;\n        padding: 0;\n      }\n      .grid-cell-text {\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        height: 100%;\n        background-color: steelblue;\n        color: white;\n        font-size: 18px;\n      }\n      .droppable-cell {\n        background-color: lightgray;\n      }\n      .table-container {\n        display: flex;\n        position: absolute;\n        left: 550px;\n        top: 30px;\n        margin-top: 0px;\n        overflow: hidden;\n      }\n    "))
  ),
  div(class = "table-container",
      div(class = "grid-table", id = "my_grid",
          div(class = "grid-row",
              div(class = "grid-cell grid-cell-text", "my_grid"),
              div(id = "droppable_cell_1", class = "grid-cell droppable-cell", ""),
              div(id = "droppable_cell_2", class = "grid-cell droppable-cell", ""),
              div(id = "droppable_cell_3", class = "grid-cell droppable-cell", ""),
              div(id = "droppable_cell_4", class = "grid-cell droppable-cell", ""),
              div(id = "droppable_cell_5", class = "grid-cell droppable-cell", ""),
              div(id = "droppable_cell_6", class = "grid-cell droppable-cell", ""),
              div(id = "droppable_cell_7", class = "grid-cell droppable-cell", ""))
      ),
      orderInput('letters', 'Letters', items = LETTERS[1:7],
                 connect = connections) # 上面定义的连接目标
  )
)

server <- function(input, output, session) {
}

shinyApp(ui, server)

问题原因

  1. 仅通过connect参数指定目标id不够,自定义网格容器my_grid未被初始化为可接收拖拽的droppable元素
  2. 网格单元格是独立的div,但没有配置对应的拖拽接收逻辑
  3. table-container的overflow: hidden样式可能干扰拖拽事件的检测

修正方案

需要给网格容器和单元格添加droppable特性,并处理拖拽后的元素放置逻辑:

library(shiny)
library(shinyjqui)

ui <- fluidPage(
  tags$head(
    tags$style(HTML(".grid-table {\n        width: 150px;\n        border-collapse: collapse;\n      }\n      .grid-cell {\n        width: 100%;\n        height: 50px;\n        border: 1px solid black;\n        background-color: white;\n        text-align: center;\n        margin: 0;\n        padding: 0;\n      }\n      .grid-cell-text {\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        height: 100%;\n        background-color: steelblue;\n        color: white;\n        font-size: 18px;\n      }\n      .droppable-cell {\n        background-color: lightgray;\n      }\n      .table-container {\n        display: flex;\n        position: absolute;\n        left: 550px;\n        top: 30px;\n        margin-top: 0px;\n      }\n    "))
  ),
  div(class = "table-container",
      # 将网格容器设置为droppable,并允许接收orderInput的元素
      jqui_droppable(
        div(class = "grid-table", id = "my_grid",
            div(class = "grid-row",
                div(class = "grid-cell grid-cell-text", "my_grid"),
                div(id = "droppable_cell_1", class = "grid-cell droppable-cell", ""),
                div(id = "droppable_cell_2", class = "grid-cell droppable-cell", ""),
                div(id = "droppable_cell_3", class = "grid-cell droppable-cell", ""),
                div(id = "droppable_cell_4", class = "grid-cell droppable-cell", ""),
                div(id = "droppable_cell_5", class = "grid-cell droppable-cell", ""),
                div(id = "droppable_cell_6", class = "grid-cell droppable-cell", ""),
                div(id = "droppable_cell_7", class = "grid-cell droppable-cell", ""))
        ),
        options = list(
          accept = ".ui-sortable-handle", # 接收orderInput中的拖拽元素
          drop = JS("function(event, ui) {
            // 将拖拽的元素添加到第一个空的单元格中
            $(ui.draggable).appendTo($(this).find('.droppable-cell:empty').first());
            // 移除原orderInput中的元素
            ui.draggable.remove();
          }")
        )
      ),
      orderInput('letters', 'Letters', items = LETTERS[1:7],
                 connect = 'my_grid')
  )
)

server <- function(input, output, session) {
}

shinyApp(ui, server)

关键修改说明

  • 使用jqui_droppable()初始化网格容器,指定accept规则匹配orderInput的拖拽元素
  • 通过drop回调函数处理元素放置逻辑,将拖拽元素添加到第一个空的单元格中
  • 移除table-container的overflow: hidden,避免干扰拖拽事件
  • 简化connect参数为单个目标id

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:30:01