Hello,
Yes, the onBeforeDataRender
event fires only when Gantt needs to repaint more than one task. But Gantt doesn’t have a universal event that fires before Gantt starts repainting a single task. There is no easy solution for that use case.
You need to detach React elements by using different event handlers. For example, the task is repainted when you click on a task. But you need to use the onBeforeTaskSelected
event handler because the onTaskClick
event fires after the data is repainted.
While dragging a task, Gantt calls the onTaskDrag
event. You can detach React elements there.
The onBeforeDataRender
event fires in the following cases:
• when you load tasks with the parse or load method
• when you load child tasks by expanding their parent task and branch_loading is enabled
• when you collapse or expand tasks
• when you close the lightbox
• when you delete a task
• when you vertically reorder a task
• when the size of the Gantt container is increased/decreased
• when Gantt is initialized
• when a task is auto-scheduled(because Gantt repaints several tasks)
• when you use the following methods:
render
resetLayout
batchUpdate
addTask
addLinkclearAll
close
open
expand
collapse
createTask
deleteTask
exportToExcel
exportToICal
exportToJSON
exportToMSProject
exportToPDF
exportToPNG
exportToPrimaveraP6
groupBy
importFromExcel
importFromMSProject
importFromPrimaveraP6
init
deleteTask
undo
redo
refreshData
sort
autoSchedule
And still, it won’t work in all cases. For example, Gantt repaints the whole task row when you start creating a link. But there is no event for that.
I added a feature request to our internal bug tracker to add an event that will fire before Gantt starts repainting a task. The dev team will add it in the future, but I cannot give you any ETA.
For now, you need to detach React elements in different event handlers. It is not a complete solution, but at least it will make the things better:
function detachReactNodes(){
var nodes1 = document.querySelectorAll(`.gantt_cell[data-column-index="3"]`)
nodes1.forEach(function (node) {
ReactDOM.unmountComponentAtNode(node);
});
var nodes2 = document.querySelectorAll(`.gantt_cell[data-column-index="4"]`)
nodes2.forEach(function (node) {
ReactDOM.unmountComponentAtNode(node);
});
}
function detachSpecificReactNode(id) {
ReactDOM.unmountComponentAtNode(document.querySelector(`[data-task-id="${id}"] .gantt_cell[data-column-index="3"]`));
ReactDOM.unmountComponentAtNode(document.querySelector(`[data-task-id="${id}"] .gantt_cell[data-column-index="4"]`));
}
gantt.attachEvent("onBeforeDataRender", function () {
detachReactNodes();
});
gantt.attachEvent("onBeforeTaskSelected", function (id, e) {
detachSpecificReactNode(id);
return true;
});
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
detachSpecificReactNode(id);
});
let linkAdd = null;
gantt.attachEvent("onMouseMove", function (id, e) {
if (document.querySelector(".gantt_link_direction") && linkAdd === null) {
detachSpecificReactNode(id);
linkAdd = "started";
}
if (linkAdd && !document.querySelector(".gantt_link_direction")) {
linkAdd = null;
}
});
Here is the updated React demo:
https://files.dhtmlx.com/30d/bcac2d270e7cf8f74f9271d74ffc489b/reactive-gantt+gantt-instance+react-components.zip