使用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)
问题原因
- 仅通过
connect参数指定目标id不够,自定义网格容器my_grid未被初始化为可接收拖拽的droppable元素 - 网格单元格是独立的div,但没有配置对应的拖拽接收逻辑
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
相关产品推荐
相关产品推荐

