webix

How to add a click event on webix gantt task


I use the first time webix gantt. Before, is used dhtmlx gantt (developed from the same company),

On dhtmlx gantt, there was onTaskClick event. But on webix gantt, this event is missing?

Does someone knows how to add a onTaskClick event?


Solution

  • There is no such event in Webix Gantt, but that's not a problem.

    If you want to track selection of tasks, use $observe on the reactive state for the selected property:

    $$("gtt").getState().$observe("selected", id => {
      console.log(id);
    });
    

    If you need any clicks, you need to do a bit more, but it's possible. There's no private code in Gantt, each part of the UI is defined as an ES6 class. So to change something in the UI or its behavior, you need to redefine some classes.

    Gantt chart is reachable as gantt.views["chart/bars"]. Let's redefine it and add a global app event:

    class bars extends gantt.views["chart/bars"] {
       /**
         * Sets action of bar item click
         * @param {(string|number)} id  - ID of the clicked item
       */
       ItemClickHandler(id) {
          super.ItemClickHandler(id);
    
          // the check is optional, leave it if 
          // you do not want to track
          // clicks on group items in
          // display:"resources"
          if (!this.Bars.getItem(id).$group) {
            this.app.callEvent("onTaskClick", [id]);
          }
       }
    }
    

    Next, apply the override:

    
    webix.ui({
        view: "gantt",
        id:"gtt",
        url: "https://docs.webix.com/gantt-backend/",
        override: new Map([
          [gantt.views["chart/bars"], bars]
        ])
    });
    

    Now you can track the event like:

    gantt1.$app.attachEvent("onTaskClick", id => {
        webix.message("Clicked " + id);
    });
    

    If you would rather have this event on gantt obj itself, not on its $app property, you can "channel" the event:

    webix.protoUI({
        name:"my-gantt",
        $init: function(){
          this.$app.attachEvent("app:task:click", id => {
            this.callEvent("onTaskClick", [id]);
          });
        }
    }, webix.ui.gantt);
    
    webix.ui({
        view: "my-gantt",
        id:"gtt",
        url: "https://docs.webix.com/gantt-backend/",
        override: new Map([
          [gantt.views["chart/bars"], bars]
        ])
    });
    

    ...and later listen to it like a usual Webix widget event:

    gantt1.attachEvent("onTaskClick", id => {
        webix.message("Clicked " + id);
    });
    

    The overall example is https://snippet.webix.com/p0sardik

    If you also want to track Tree clicks, you will need to override gantt.views.tree in a similar way (redefine the ItemClickHandler method).