Rails6中如何使用jQuery UI resizable调整水平日期图表的起止日期
问题原因
- jQuery UI Resizable 默认会修改目标元素自身的宽高,你给.end_cell添加e方向拖拽时,向右拉伸元素宽度不会挤占左侧已有元素,所以看起来正常;但向左拉伸时,左侧的.start_cell和中间normal_cell已经占了位置,float布局下元素无法向左挤占空间,所以可拖拽范围极小。
- 你的核心需求是调整日期区间的起止位置,本质是移动start、end节点的位置,不是拉伸单个单元格的宽度,所以需要改写默认的resize逻辑。
实现代码
$(function() { // 单个单元格总占位宽度:内容20px + 右边框1px + 右margin1px = 22px,修改单元格样式后需要同步调整该值 const CELL_WIDTH = 22; // 给start_cell加左侧(w)拖拽手柄,end_cell加右侧(e)拖拽手柄 ApplyResizablePluginToCol($(".start_cell"), 'w'); ApplyResizablePluginToCol($(".end_cell"), 'e'); function ApplyResizablePluginToCol(elements, handleDir){ elements.resizable({ maxHeight: 20, minHeight: 20, minWidth: 20, distance: 5, handles: handleDir, grid: [CELL_WIDTH, 0], // 水平方向按单元格宽度步长拖拽,保证每次调整对应一个单元格的增减 start: function(event, ui) { // 记录元素原始宽度、所属行容器,后续重置宽度用 $(this).data('originalWidth', ui.originalSize.width); $(this).data('rowContainer', $(this).closest('[id^="product_"]')); }, resize: function(event, ui) { // 重置元素宽度为原始值,不拉伸单元格本身 $(this).width($(this).data('originalWidth')); const delta = ui.size.width - ui.originalSize.width; const cellCount = Math.round(delta / CELL_WIDTH); if($(this).hasClass('start_cell')) { if(cellCount > 0) { // 向左拖拽start_cell,前面新增单元格,对应起始日期往前推 for(let i=0; i<cellCount; i++) { $(this).before('<span class="normal_cell"></span>'); } // 此处添加同步start_date的逻辑,日期减去cellCount个时间单位 } else if(cellCount < 0) { const removeCount = Math.abs(cellCount); const prevCells = $(this).prevAll('.normal_cell'); // 边界判断:最多删除start_cell前面所有的normal_cell if(prevCells.length >= removeCount) { prevCells.slice(0, removeCount).remove(); // 此处添加同步start_date的逻辑,日期加上removeCount个时间单位 } } } else if($(this).hasClass('end_cell')) { if(cellCount > 0) { // 向右拖拽end_cell,后面新增单元格,对应结束日期往后推 for(let i=0; i<cellCount; i++) { $(this).after('<span class="normal_cell"></span>'); } // 此处添加同步end_date的逻辑,日期加上cellCount个时间单位 } else if(cellCount < 0) { const removeCount = Math.abs(cellCount); const middleCells = $(this).prevUntil('.start_cell', '.normal_cell'); // 边界判断:最多删除到end_cell和start_cell相邻 if(middleCells.length >= removeCount) { middleCells.slice(0, removeCount).remove(); // 此处添加同步end_date的逻辑,日期减去removeCount个时间单位 } } } }, stop: function() { // 拖拽结束后可在此处触发AJAX请求,提交新的起止日期到Rails后端保存 console.log("日期区间调整完成"); } }); } });
注意事项
- 每个单元格对应的时间粒度可以根据业务需求调整,比如单格代表1天、1周、1个月,对应日期同步逻辑修改增减的时间单位即可
- 如果你的Rails6项目开启了Turbo/Turbolinks,需要把初始化逻辑绑定到
turbo:load事件,避免页面跳转后功能失效:
$(document).on('turbo:load', function() { // 将上述初始化逻辑放到此处 })
内容的提问来源于stack exchange,提问作者jissy
相关产品推荐
相关产品推荐

