How to display subtasks together after searching for parent tasks

Hello,

Search for the parent task, and even the child task together to display the Gantt chart.
Please help thank you.

Hello Kevin,
If you want to find a task and display it with all its parents, here is the first snippet:
http://snippet.dhtmlx.com/94180266e
If you want to find a task and display all its children, here is the second snippet:
http://snippet.dhtmlx.com/5/1d16c2963

If you need something else, please clarify.

Hello Ramil,

I need this feature.
Https://snippet.dhtmlx.com/290f71297
But there are some problems. If I narrow down the hierarchy, I can’t search for tasks.
Slides3
Slides4

Hello Ramil,

It is ok, thank you.

document.addEventListener(“DOMContentLoaded”, function(event) {
var filterValue = “”;
gantt.$doFilter = function(value){
filterValue = value;
gantt.refreshData();
}

gantt.attachEvent(“onGanttRender”, function(){
gantt.$root.querySelector("[data-text-filter]").value = filterValue;
})

function compare_input(id) {
var match = 0;

// check task's text
if (gantt.getTask(id).text.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
	match = true;

return match;
}

function all_parents_check(id){
var show_task = false;
gantt.eachParent(function(task){
if (gantt.getTask(task.id).text.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0)
show_task = true;
}, id)
return show_task;
}

gantt.attachEvent(“onBeforeTaskDisplay”, function (id, task) {
if (compare_input(id) || all_parents_check(id)) {
return true;
}

return false;

});

var textFilter = “

Task name
“;
gantt.config.columns = [
{name:“add”, label:””, width:50, align:“left” },
{name:“text”, label:textFilter, width:250, tree:true },
{name:“start_date”, label:“Start time”, width:80, align:“center” },
{name:“duration”, label:“Duration”, width:60, align:“center” }
];

gantt.init(“gantt_here”);

gantt.load("/data");
});

Hello Kevin,
Thank you for reporting about that. Looks like, we need to add this string to find the search box after rendering the data:

gantt.attachEvent("onDataRender", function(){
  search_box = document.getElementById("search");
});  

http://snippet.dhtmlx.com/5/1d16c2963

Hello Ramil

That’s great, thank you.

Hi Ramil,
Thanks for the snippet, I’ve got the same requirement.
I’ve one issue with this. After searching the parent task, the parent tasks are loaded along with children and then clicked the parent tree icon to view the children’s tasks.
After that, trying to clear the search, but I couldn’t able to clear it. The input event listener didn’t get fired after opening the children tasks.
Please help with possible solution, thank you.

Hello,
Unfortunately, I couldn’t reproduce the issue:
https://files.dhtmlx.com/30d/db498306b8620460adb43e090628329a/vokoscreen-2020-07-10_12-16-34.mkv

Please, modify the snippet and reproduce the issue there, then click on the “Share” button and send me the link:
http://snippet.dhtmlx.com/5/1d16c2963

I have attached the code snippet for your reference.
https://snippet.dhtmlx.com/5/11f13933c 1

Steps to recreate:

  1. In the search tasks bar, type for the parent task name, and then the parent tasks will be listed.
  2. Click on the expand icon in the parent task.
  3. Now, try to clear the search. (The task didn’t get refreshed)

Hello @manzi,

I think the issue was caused by the fact that ‘input’ event listener was added only once on page start, while the filter located inside the gantt was re-generated each time gantt was rendered. Thus the input event handler was attached only until the first complete repaint of the gantt.

If you attach input event handler from onGanttRender event, all should work correctly:

var filterValue;
gantt.attachEvent('onGanttRender', () => {
  gantt.$root.querySelector('[data-text-filter]').oninput = (event) => {
    filterValue = event.target.value;
  	gantt.refreshData();
  }
  gantt.$root.querySelector('[data-text-filter]').value = filterValue || "";
});

function compareInput(id) {
  if(!filterValue){
    return true;
  }
  return gantt.getTask(id).text.toLowerCase().indexOf(filterValue.toLowerCase()) > -1;
}

function allParentsCheck(id){
  if(!filterValue){
    return true;
  }
  var show_task = false;
  gantt.eachParent(function(task){
	if (task.text.toLowerCase().indexOf(filterValue.toLowerCase()) >= 0) {
  	  show_task = true;
    }
  }, id);

  return show_task;
}

gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
  if (compareInput(id) || allParentsCheck(id)) {
     return true;
  }

  return false;
});

Just be sure to define onGanttRender before gantt.init call, so it will be called after the initial render of the gantt.

Snippet: http://snippet.dhtmlx.com/5/df7a3eb48