如何使用jqui_resizable实现orderInput项的可调整大小与文本旋转
问题:为shinyjqui拖拽项实现大小调整与文本旋转功能
我需要为带有标签A的拖拽项/按钮实现两个功能:
- 鼠标拖动调整大小
- 文本旋转
这是之前拖拽到网格表格问题的后续需求。我参考shinyjqui文档中“可调整大小:使用鼠标更改元素尺寸”的说明,尝试让目标元素支持拖拽调整大小,试过用包内的jqui_sortable函数,也写了自定义JS代码,但都没成功。请问这个需求是否可行?
附上我尝试的代码:
library(shiny) library(shinyjqui) connections <- paste0("droppable_cell_", 1) # 网格单元格ID ui <- fluidPage( tags$head( tags$script( JS( " $(document).on('shiny:connected', function() { $('#letters').resizable({ alsoResize: '.shinyjqui-sortable-item', minHeight: 20, minWidth: 20 }); }); $(function() { $('[id^=droppable_cell]').sortable({ connectWith: '#letters', drop: function(event, ui) { $(this).append(ui.draggable); } }) }); " ) ), # 样式设置 tags$style( HTML( " .grid-table { width: 150px; border-collapse: collapse; } .grid-cell { width: 100%; height: 200px; border: 1px solid black; background-color: white; text-align: center; margin: 0; padding: 5px; } .grid-cell-text { display: flex; align-items: center; justify-content: center; height: 100%; background-color: steelblue; color: white; font-size: 18px; } .droppable-cell { background-color: lightgray; } .table-container { display: flex; position: absolute; left: 10px; top: 10px; margin-top: 0px; overflow: hidden; } " ) ) ), 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", ""), ) ), orderInput('letters', 'Letters', items = LETTERS[1], connect = connections) # 关联目标容器 ) ) server <- function(input, output, session) { } shinyApp(ui, server)
解决方案
1. 实现拖拽项的大小调整
你之前的代码是给整个#letters容器绑定了resizable,但实际需要调整的是容器内的.shinyjqui-sortable-item元素。修改JS逻辑,直接给目标项绑定调整大小功能,同时优化样式确保按钮占满拖拽项空间:
$(document).on('shiny:connected', function() { // 给每个拖拽项添加可调整大小功能 $('.shinyjqui-sortable-item').resizable({ minHeight: 30, minWidth: 30, // 调整大小时同步更新内部按钮尺寸 resize: function(event, ui) { $(this).find('.btn').css({ width: '100%', height: '100%' }); } }); });
补充样式:
.shinyjqui-sortable-item .btn { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
2. 实现文本旋转功能
添加一个触发按钮,通过点击累加旋转角度,用CSS的transform: rotate()实现文本旋转:
在JS中添加旋转逻辑:
// 文本旋转功能,每次点击旋转90度 let rotation = 0; $(document).on('click', '#rotate-btn', function() { rotation += 90; $('.shinyjqui-sortable-item .btn').css('transform', `rotate(${rotation}deg)`); });
在UI中添加旋转按钮:
actionButton("rotate-btn", "旋转文本")
完整修改后的代码
library(shiny) library(shinyjqui) connections <- paste0("droppable_cell_", 1) # 网格单元格ID ui <- fluidPage( tags$head( tags$script( JS( " $(document).on('shiny:connected', function() { // 给每个拖拽项添加可调整大小功能 $('.shinyjqui-sortable-item').resizable({ minHeight: 30, minWidth: 30, // 调整大小时同步更新内部按钮尺寸 resize: function(event, ui) { $(this).find('.btn').css({ width: '100%', height: '100%' }); } }); }); $(function() { $('[id^=droppable_cell]').sortable({ connectWith: '#letters', drop: function(event, ui) { $(this).append(ui.draggable); } }) }); // 文本旋转功能 let rotation = 0; $(document).on('click', '#rotate-btn', function() { rotation += 90; $('.shinyjqui-sortable-item .btn').css('transform', `rotate(${rotation}deg)`); }); " ) ), # 样式设置 tags$style( HTML( " .grid-table { width: 150px; border-collapse: collapse; } .grid-cell { width: 100%; height: 200px; border: 1px solid black; background-color: white; text-align: center; margin: 0; padding: 5px; } .grid-cell-text { display: flex; align-items: center; justify-content: center; height: 100%; background-color: steelblue; color: white; font-size: 18px; } .droppable-cell { background-color: lightgray; } .table-container { display: flex; position: absolute; left: 10px; top: 10px; margin-top: 0px; overflow: hidden; } .shinyjqui-sortable-item .btn { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; } " ) ) ), actionButton("rotate-btn", "旋转文本"), 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", ""), ) ), orderInput('letters', 'Letters', items = LETTERS[1], connect = connections) # 关联目标容器 ) ) server <- function(input, output, session) { } shinyApp(ui, server)
说明
- 大小调整:直接给拖拽项绑定resizable,同时确保内部按钮占满项的空间,避免调整大小时按钮错位
- 文本旋转:通过点击按钮累加旋转角度,你也可以根据需求改成拖拽旋转、右键菜单触发等方式
内容的提问来源于stack exchange,提问作者TarJae
相关产品推荐
相关产品推荐

