How to Filter Tasks in a JavaScript Gantt – DHTMLX Video Tutorial

| Leave a comment

Here we go with a new video tutorial about JavaScript Gantt configuration. We’ll learn a common approach to implementing filtering and searching for tasks in the grid of dhtmlxGantt:

Let’s take a look at the example of a basic text filter. A user types something – and we display only the tasks that match the selection:
Filtering tasks in DHTMLX Gantt

Such filters consist of two parts:

  • the UI control that allows a user to select the filter criteria
  • the code that will manage the visibility of rows in Gantt

We already know how to add UI controls, and we know that we’ll update filters on the user input.

Now, how do we filter tasks in Gantt?

There is no filter tasks method in dhtmlxGantt. Instead, there is an API event called onBeforeTaskDisplay:

gantt.attachEvent("onBeforeTaskDisplay", function(id, task){
    if (task.priority == "high"){
        return true;
    }
    return false;
});

Check the API in the documentation >

This event is called for each task during a complete repaint of Gantt data. We can add a handler for this event to our code, and skip rendering of tasks that don’t match the filter value.

To begin with, we add a text field to the grid header:

var textFilter = "<input data-text-filter type='text' oninput='gantt.$doFilter(this.value)'>"
  gantt.config.columns = [
    {name: "text", label: textFilter, tree: true, width: '*', resize: true},
    {name: "start_date", align: "center", resize: true},
    {name: "duration", align: "center"}
  ];

Inside the oninput handler we’ll store the current value of the filter and trigger the repaint of the Gantt using the gantt render method:

var filterValue = "";
  var delay;
  gantt.$doFilter = function(value){
    filterValue = value;
    clearTimeout(delay);
    delay = setTimeout(function(){
      gantt.render();
      gantt.$root.querySelector("[data-text-filter]").focus();

    }, 200)
  }

The gantt render method causes a complete repaint of the Gantt chart, during which the onBeforeTaskDisplay event will be called for each task. Then we check whether the task matches the filter criteria, and decide whether to show it or not.

  gantt.attachEvent("onBeforeTaskDisplay", function(id, task){
   if(!filterValue) return true;

    var normalizedText = task.text.toLowerCase();
    var normalizedValue = filterValue.toLowerCase();
    return normalizedText.indexOf(normalizedValue) > -1;
  });

At this stage, you may want to have a multiline header in your grid, for example, in order to show a column name above your filter.
Multiline headers in DHTMLX Gantt
The bad news is that Gantt doesn’t have a built-in config for multiline headers. But we can bypass it in the same way as we added the filter in the first place using custom HTML content. We can display multiple rows inside the column label:

var scaleHeight = gantt.config.scale_height;
  var textFilter = [
        "<div class='gantt-sub-header' style='line-height:"+scaleHeight/2+"px'>",
        "<div>Name</div>",
        "<div>Search: <input data-text-filter type='text' oninput='gantt.$doFilter(this.value)'></div>",
        "</div>"
    ].join("");

Implementing col span or row span won’t be so trivial, so hopefully, you won’t need it.

We invite you to try filtering tasks yourself building your own JavaScript Gantt with the help of our free evaluation version. Follow the steps described in this article and our video tutorial or consult our technical support team if any questions arise.

Enjoy your Gantt and stay tuned for future tutorials!

Leave a Reply