如何为dhtmlx Gantt Chart中所有任务更新不同的开始日期
实现dhtmlx Gantt任务独立日期更新(点击任务时设置对应自定义日期)
我看你已经搭好了Gantt的基础框架,现在需要把Obj数组里的自定义日期和每个任务绑定,实现点击任务时单独更新其开始日期。下面是调整后的完整解决方案:
核心思路
- 任务与自定义日期的映射:通过任务的
text(比如"Task #1"对应item1),把Obj中的日期和对应任务关联起来 - 日期格式兼容处理:将
Obj里的带时区ISO日期转换为Gantt支持的DD-MM-YYYY格式 - 绑定点击事件:监听任务点击动作,触发对应任务的日期更新逻辑
修改后的完整代码
<!DOCTYPE html> <html> <head> <link rel='stylesheet' type='text/css' href='http://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css'> <script src='http://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js'></script> <style> .gantt_custom_button { background-color: rgb(206, 206, 206); position: absolute; right: -10px; top: 5px; width: 20px; height: 26px; border-radius: 0; } </style> </head> <body> <div id='gantt_here' style='width:100%; height:500px;'></div> <script> var task1 = { 'data': [{ 'id': 1, 'text': 'Project #1', 'start_date': '01-04-2019', 'duration': 2, 'order': 10, 'progress': 0.4, 'open': true }, { 'id': 2, 'text': 'Task #1', 'start_date': '02-04-2019', 'duration': 1, 'order': 10, 'progress': 0.6, 'parent': 1 }, { 'id': 3, 'text': 'Task #2', 'start_date': '03-04-2019', 'duration': 2, 'order': 20, 'progress': 0.6, 'parent': 1 }, { 'id': 4, 'text': 'Task #3', 'start_date': '02-04-2019', 'duration': 1, 'order': 10, 'progress': 0.6, 'parent': 1 }], 'links': [{ 'id': 1, 'source': 1, 'target': 2, 'type': '1' }, { 'id': 2, 'source': 2, 'target': 3, 'type': '0' }, { 'id': 3, 'source': 3, 'target': 4, 'type': '0' }] }; // 辅助函数:将带时区的ISO日期转换为Gantt支持的DD-MM-YYYY格式 function convertToGanttDate(isoDate) { if (!isoDate) return null; const date = new Date(isoDate); const day = String(date.getDate()).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始计数,需+1 const year = date.getFullYear(); return `${day}-${month}-${year}`; } // 辅助函数:从任务文本提取对应item的key(比如Task #1 → item1) function getTaskItemKey(taskText) { const matchResult = taskText.match(/Task #(\d)/); return matchResult ? `item${matchResult[1]}` : null; } // 自定义日期数据源 const customDateSource = [{ Id: 575, items: { item1: '2020-12-08T10:00:00.000+0000', item2: '2020-11-12T00:00:00.000+0000', item3: '2020-12-08T10:00:00.000+0000', item4: null, item5: '2020-12-08T10:00:00.000+0000' }, active: false }]; const taskDates = customDateSource[0].items; // 可选:初始化时直接给任务设置自定义日期(不需要的话可以注释这段) task1.data.forEach(task => { const itemKey = getTaskItemKey(task.text); if (itemKey && taskDates[itemKey]) { task.start_date = convertToGanttDate(taskDates[itemKey]); } }); // 配置Gantt时间刻度 gantt.config['scales'] = [{ unit: 'day', step: 1, format: '%d %M' }]; // 绑定任务点击事件:点击时更新对应任务的开始日期 gantt.attachEvent("onTaskClick", function(taskId, event) { const targetTask = gantt.getTask(taskId); const itemKey = getTaskItemKey(targetTask.text); if (itemKey && taskDates[itemKey]) { const newStartDate = convertToGanttDate(taskDates[itemKey]); if (newStartDate) { // 更新任务日期 gantt.updateTask(taskId, { start_date: newStartDate }); // 刷新Gantt视图 gantt.render(); console.log(`任务${targetTask.text}已更新日期:${newStartDate}`); } } return true; // 保留默认点击行为 }); gantt.init('gantt_here'); gantt.parse(task1); </script> </body> </html>
关键细节说明
- 日期转换:Gantt默认使用
DD-MM-YYYY格式的日期字符串,所以需要把Obj里的ISO标准日期转成兼容格式,避免解析错误。 - 任务映射:通过正则从任务文本中提取编号,自动对应到
items里的键,不用手动写死每个任务的关联关系,扩展性更好。 - 点击事件处理:使用Gantt的
onTaskClick事件监听点击动作,调用gantt.updateTask更新任务数据后,必须调用gantt.render()刷新视图才能看到变化。
另外,你原来的forLaunch函数逻辑存在问题(循环第一个key就直接返回,导致刻度显示异常),如果不需要自定义刻度文本可以暂时去掉;如果需要这部分功能,可以告诉我你的具体需求,我再帮你调整。
内容的提问来源于stack exchange,提问作者fullstackdeveloper




