DHTMLX / gantt

GPL version of Javascript Gantt Chart
https://dhtmlx.com/docs/products/dhtmlxGantt/
GNU General Public License v2.0
1.44k stars 320 forks source link

Inline Editors not working after component destroy in Angular #86

Open AntoRin opened 1 year ago

AntoRin commented 1 year ago

Dhtmlx-gantt version: 7.1.13

I am using the free version of dhtmlx-gantt. This means that I won't be able to initialize a new gantt instance on component render. I perform some clean-up of the gantt instance on destroy, which is mostly removing all events and tooltips. Although this has been working well so far, the inline editors only work the first time. After the first time, none of the events related to the inline events fire (events that are created using the gantt.ext.inlineEditors.attachEvent method).

AntoRin commented 1 year ago

I've found out that using the gantt.init method on an already initialized gantt instance makes the inline editors unusable.

Any workarounds for this?

gearcoded commented 1 year ago

@AntoRin, It is a bug in Gantt that the inline editor events stop working after using the init and resetLayout methods. The dev team will fix the bug in the future, but I cannot give you any ETA.

As a workaround, you can detach events and attach them again in the onGanttReady event handler:

var onSave_id = null;
gantt.attachEvent("onGanttReady", function () {
  if (onSave_id) gantt.ext.inlineEditors.detachEvent(onSave_id)

  onSave_id = gantt.ext.inlineEditors.attachEvent("onSave", function (state) {
    gantt.message("onSave event");
    var col = state.columnName;
    if (gantt.autoSchedule && (col == "start_date" || col == "end_date" || col == "duration")) {
      gantt.autoSchedule();
    }
  });
});

Here is the snippet: https://snippet.dhtmlx.com/5/a6ca5c108

AntoRin commented 1 year ago

Hi, @gearcoded, thanks for the reply.

This solution works. Although I was already detaching inline editor events when the component destorys, I wasn't attaching them back during the onGanttReady event. Apparently, that's necessary.

And for those who are referring to this later on, you can use the following method to detach all events from the inline editor instead of having to store reference to each event using the returned event ID and detaching them one by one.

gantt.ext.inlineEditors.detachAllEvents();

CedricHg commented 11 months ago

@AntoRin, It is a bug in Gantt that the inline editor events stop working after using the init and resetLayout methods. The dev team will fix the bug in the future, but I cannot give you any ETA.

As a workaround, you can detach events and attach them again in the onGanttReady event handler:

var onSave_id = null;
gantt.attachEvent("onGanttReady", function () {
  if (onSave_id) gantt.ext.inlineEditors.detachEvent(onSave_id)

  onSave_id = gantt.ext.inlineEditors.attachEvent("onSave", function (state) {
    gantt.message("onSave event");
    var col = state.columnName;
    if (gantt.autoSchedule && (col == "start_date" || col == "end_date" || col == "duration")) {
      gantt.autoSchedule();
    }
  });
});

Here is the snippet: https://snippet.dhtmlx.com/5/a6ca5c108

This snippet no longer works on the current version of DHTMLX Gantt, because the attachEvent function for InlineEditorEvents now returns a boolean rather than a string id. I have not yet been able to find how I can get this id in the current version for detaching purposes.

AntoRin commented 11 months ago

@AntoRin, It is a bug in Gantt that the inline editor events stop working after using the init and resetLayout methods. The dev team will fix the bug in the future, but I cannot give you any ETA. As a workaround, you can detach events and attach them again in the onGanttReady event handler:

var onSave_id = null;
gantt.attachEvent("onGanttReady", function () {
  if (onSave_id) gantt.ext.inlineEditors.detachEvent(onSave_id)

  onSave_id = gantt.ext.inlineEditors.attachEvent("onSave", function (state) {
    gantt.message("onSave event");
    var col = state.columnName;
    if (gantt.autoSchedule && (col == "start_date" || col == "end_date" || col == "duration")) {
      gantt.autoSchedule();
    }
  });
});

Here is the snippet: https://snippet.dhtmlx.com/5/a6ca5c108

This snippet no longer works on the current version of DHTMLX Gantt, because the attachEvent function for InlineEditorEvents now returns a boolean rather than a string id. I have not yet been able to find how I can get this id in the current version for detaching purposes.

Hey, @CedricHg, thanks for the reply. I have been using this solution for a while now following @gearcoded 's advice. Seems to be working fine. Although let me know when this is totally resolved.

gearcoded commented 11 months ago

@AntoRin and @CedricHg, that seems to be an issue with the types, though the attachEvent function should work correctly. In fact, it is not necessary to save the IDs of the event handlers for the inline editors. It can work if you don't do that. The only difference is that the event handler ID will be different. So, as a workaround, you can attach the inline editor events in the onGanttReady event handler:

gantt.attachEvent("onGanttReady", function () {
    gantt.ext.inlineEditors.attachEvent("onEditStart", function (state) {
        if (state.columnName == "progress") {
            const node = gantt.ext.inlineEditors._placeholder.firstChild.firstChild
            node.value = parseInt(node.value * 100);
        }
    });
});

And here is the snippet: https://snippet.dhtmlx.com/be56ezhd

I will notify you when the issue is fixed.

AntoRin commented 10 months ago

@gearcoded, appreciate that. Thank you.