Using angular external component within the gantt column

our app is a hybrid app (Angular and AngularJS side-by-side)
We have a Gantt timeline component in angular and we are passing columns to the component. and we need to render an external component inside one of these columns when we try that it doesn’t show the component and the column is empty.

<timeline-component [data]="data" [links]="links" [columns]="timelineColumns" />

columns = [{
      name: "text",
      label: `text`,
      tree: true,
      resize: true,
      width: '*',
      min_width: 300,
      template: (task, node) => {
        return  `<span>${task.text}</span>`
      }
    }, {
      name: "status",
      resize: true,
      label: `status`,
      align: "left",
      width: 100,
      template: function (task, node) {
        return ` return `<status-component [task]=${task}></status-component>`;`;
      }
    }]

Hello Wafia,
To show Angular components inside Gantt, Angular needs to render them.
If you use the template function, you can only show HTML elements. To show Angular elements, you need to use the onrender method:
https://docs.dhtmlx.com/gantt/desktop__specifying_columns.html#modifyingcellsafterrendering

Here are examples of how it can be implemented:
https://files.dhtmlx.com/30d/f4fddc6764a97988db0fe6591f7ec39f/angular16+onrender+kendo-button.zip

https://files.dhtmlx.com/30d/7411424b79b03cd87fa5a6d4d13bc72f/angular13+onrender+routing.zip

https://files.dhtmlx.com/30d/bcbe40b238a361c80c0520cb3fd1b031/angular10+onrender+material_button.zip

Also, Gantt doesn’t have a built-in way to detach Angular components. You need to do it manually with the help of various event handlers, for example, in the onBeforeDataRender event handler:
https://docs.dhtmlx.com/gantt/api__gantt_ondatarender_event.html

Unfortunately, I don’t have examples for Angular, but here is an example for React:

    gantt.config.columns = [
      { name: "text", label: "Task name", tree: true, width: "*" },
      { name: "start_date", label: "Start time", align: "center" },
      { name: "duration", label: "Duration", align: "center" },
      {
        name: "buttons1",
        label: "Buttons 1",
        align: "center",
        width: 100,
        onrender: (item, node) => {
          return (
            <Button variant="outlined" color="primary" size="small" onClick={() => alert("This is an Outlined Material Button")}>
              outlined
            </Button>
          );
        },
      },
      {
        name: "buttons2",
        label: "Buttons 2",
        align: "center",
        width: 120,
        onrender: (item, node) => {
          return (
            <Button variant="contained" color="secondary" onClick={() => alert("This is a Contained Material Button")}>
              contained
            </Button>
          );
        },
      },
      { name: "add", label: "", width: 44 },
    ];
    gantt.config.external_render = {
      isElement: (element) => {
        return React.isValidElement(element);
      },
      renderElement: (element, container) => {
        ReactDOM.render(element, container);
      },
    };

    gantt.attachEvent("onGanttScroll", function (left, top) {
      //detachReactNodes()
      ReactDOM.unmountComponentAtNode(gantt.$root);
    });

    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 are the React demos:
https://files.dhtmlx.com/30d/bcac2d270e7cf8f74f9271d74ffc489b/reactive-gantt+gantt-instance+react-components.zip

https://files.dhtmlx.com/30d/6b556ee8ec876eb18658f532c5a20ca1/reactive-gantt+gantt-instance+react-components+grid_header.zip

1 Like