Integrating DHTMLX Gantt with Suite’s Toolbar Widget for Convenient Project Management

Hello everyone and welcome to a new tutorial of the series dedicated to customizing our top products with additional functionalities. This time, we want to share with you a way to simplify the interaction with a DHTMLX-based Gantt chart by integrating it with a toolbar. For this purpose, we’ll use the Suite’s Toolbar widget, which is smoothly combined with DHTMLX Gantt.

Example of Using a Toolbar in a Gantt Chart

A full-featured Gantt chart is a complex and time-proven instrument used for managing workflows in projects of any complexity. However, it often takes time to master its functional versatility and make the most of it in real projects. Therefore, it can be reasonable to complement a Gantt chart with auxiliary controls like a toolbar that facilitates its usage. In the example below, you can see a JavaScript Gantt chart built based on DHTMLX with a toolbar implemented with the UI widget from our Suite library.
Check the sample >

The toolbar allows end-users to conveniently perform a wide range of operations in the Gantt chart such as:

  • undo/redo changes
  • collapse and expand all tasks at once
  • highlight critical tasks
  • search (filter) tasks
  • set the displayed date range
  • export data to PDF, PNG, Excel, MSP, and Primavera formats.

Now we can proceed to the technical aspects of adding a toolbar in a JavaScript Gantt.

Step 1: Defining the Toolbar Menu

Let us start with defining the appearance of the toolbar menu (i.e. toolbar icons) using the toolbarItems variable. In the icon field, you specify the class name for the icons. The icons are taken from the web font enabled in the HTML tab (material design icons).

First, here is a CSS part:

<link href="https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/4.4.95/css/materialdesignicons.css?v=6.4.2" media="all" rel="stylesheet" type="text/css">

Now, we can proceed with the JavaScript code:

const toolbarItems = [
{
    icon: "mdi mdi-undo-variant",
    id: "undo"
},
{
    icon: "mdi mdi-redo-variant",
    id: "redo"
},
{
    icon: "mdi mdi-folder",
    id: "close"
},

You can specify the type of toolbar elements (e.g, input, datepicker, etc.). Otherwise, the default element type will be used.

{
    id: "search",
    type: "input",
    placeholder: "Search tasks",
    icon: "mdi mdi-magnify",
    width: 150,
},
{
    type: "datePicker",
    value: new Date(2025, 03, 01),
    label: "Start:",
    width: 150,
    id: "start_date",
    editable: true,
    mark: (date) => {
        if (date.getDay() === 5) return "highlight-date";
    },
},

In the items parameter of the array, you specify child elements for the drop-down list.

{
    value: "Export",
    id: "export",
    items: [
        {
            value: "Export To PDF",
            id: "pdf"
        },
        {
            value: "Export To PNG",
            id: "png"
        },
Step 2: Creating and Initializing Toolbar

The next step is to create a new instance of the Toolbar and initialize it in a container with the toolbar_container ID. Then, you load the data with the toolbar items.

const toolbar = new dhx.Toolbar("toolbar_container", { css: "dhx_toolbar--bordered" });
toolbar.data.parse(toolbarItems);
Step 3: Adding Handlers for Click Events

After that, you need to specify event handlers that will fire when buttons are clicked/text is entered/date is selected.

Let us start with click events.

toolbar.events.on("click", function (id, e) {
    switch (id) {

For the expand button, you iterate through each task using the eachTask() method and call the open() method to open the task. All of this is done inside the batchUpdate() method so that the changes are rendered only once.

case "open":
    gantt.batchUpdate(function (task) {
        gantt.eachTask(function (task) {
            task.$open = true;
        })
    })
    break;

For the collapse button, you do the same but using the close() method.

case "close":
    gantt.batchUpdate(function (task) {
        gantt.eachTask(function (task) {
            task.$open = false;
        })
    })
    break;

For undo and redo buttons, you use undo() and redo() methods correspondingly.

case "undo":
    gantt.undo()
    break;
case "redo":
    gantt.redo()
    break;

The element with the critical ID enables and disables the highlight_critical_path config to add or remove the highlighting of critical tasks.

case "critical":
    gantt.config.highlight_critical_path = !gantt.config.highlight_critical_path;
    gantt.render()
    break;
}

Then, come the exporting options. For export to the Excel format, you should use the visual parameter to add a Gantt-like timeline to the exported file.

case "pdf":
    gantt.exportToPDF()
    break;
case "png":
    gantt.exportToPNG()
    break;
case "excel":
    gantt.exportToExcel({
        visual: true
    })
    break;
case "msp":
    gantt.exportToMSProject()
    break;
case "p6":
    gantt.exportToPrimaveraP6()
    break;
Step 4: Adding Event Handlers to Input Elements

Next, you need to add event handlers for input elements. If it is a search field, you change the value of the filterValue variable to a new one and call refreshData to render the changes.

toolbar.events.on("input", function (id, value) {
    if (id == "search") {
        filterValue = value;
        gantt.refreshData()
    }
Step 5: Filtering Tasks

Tasks are filtered inside the onBeforeTaskDisplay event handler. If it returns false, the task won’t be displayed. There, you convert the task name to lowercase and see if the task name contains a value from filterValue (also converted to lowercase).

let filterValue = "";
gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
    if (filterValue && task.text.toLowerCase().indexOf(filterValue) == -1) {
        return false;
    }
    return true;
});
Step 6: Updating Date Range

If there is another event in the input handler, it means that the displayed date range of the task should be updated.

toolbar.events.on("input", function (id, value) {
    if (id == "search") {
        filterValue = value;
        gantt.refreshData()
    }
    else {
        updateDateRange()
    }
});

In the updateDateRange function, you specify HTML elements with dates.

function updateDateRange() {
    const startDateEl = document.querySelector("#start_date");
    const endDateEl = document.querySelector("#end_date");

After that, you convert the values from string to date.

const startDate = gantt.date.str_to_date("%d/%m/%y")(startDateEl.value);
const endDate = gantt.date.str_to_date("%d/%m/%y")(endDateEl.value);

Then, you specify dates for gantt.config.start_date and gantt.config.end_date parameters. Now, you use the render() method to render the changes.

gantt.config.start_date = startDate;
gantt.config.end_date = endDate;
gantt.render()

The inputBlur event is triggered when the element loses focus. Check the ID value, and if there is the start_date or end_date parameter, then call the updateDateRange function. It must be done after some period of time, because if you do it right away, the HTML elements will still have the old value.

toolbar.events.on("inputBlur", function (id) {
    if (id == "start_date" || id == "end_date") {
        setTimeout(function () {
            updateDateRange()
        }, 200)
    }
});
Step 7: Putting Everything Together

After completing all these configuration steps, you enable all plugins (extensions).

gantt.plugins({
    undo: true,
    critical_path: true,
    export_api: true
})

The trickiest part of this tutorial is over. Now you need to initialize your Gantt chart and load tasks using corresponding guides from our documentation.

The final result of your efforts should look similar to this sample.

Wrapping Up

As you can see from the final sample, the toolbar makes it much easier for end-users to interact with the Gantt chart. Using the Suite’s Toolbar widget, you can integrate a handy toolbar with your JavaScript Gantt with minimum time and effort. The high customizability of DHTMLX libraries allows for the implementation of solutions that fully correspond to any project requirements. If you want to give it a try, download free 30-day trial versions of our products and get down to business.

Related Materials

Advance your web development with DHTMLX

Gantt chart
Event calendar
Diagram library
30+ other JS components