Available only in PRO Edition

Dynamic Loading (on demand)

This functionality is available only in the PRO edition

By default, dhtmlxGantt loads all data at once. It may become problematic when you have a big number of tasks.

In such a situation you may use the dynamic loading mode and load data by branches (sub-projects), level by level as the user opens them.

How it works

When dynamic loading is enabled, the gantt.load("url") call will send a GET request to the specified URL, expecting the response to contain only the top-level tasks, and all the nested branches displayed as closed.

When the user clicks on the Expand icon, gantt automatically calls the load method sending the id of a clicked task to the server:

gantt.load("url?parent_id=123");

And expects the response to contain subtasks of the expanded item.

You can use the onBeforeBranchLoading event in order to modify the request url or to add some extra parameters to it.

Enabling dynamic loading

To enable the dynamic loading in the Gantt chart, you need to deal with both the client- and the server side.

gantt.config.xml_date = "%Y-%m-%d %H:%i:%s";
gantt.config.branch_loading = true;
 
gantt.init("gantt_here");
 
gantt.load("/dynamic_loading");
  • Server side:
<?php
 
include ('config.php');
 
$gantt = new JSONGanttConnector($res, $dbtype);
 
$parent_id = isset($_GET["parent_id"]) ? $_GET["parent_id"] : 0;
 
$gantt->mix("open", 0);
$gantt->mix("deep", 1);
 
$gantt->render_links("gantt_links", "id", "source,target,type");
$gantt->render_table(
    "gantt_tasks",
    "id",
    "start_date,duration,text,progress,parent",
    "", 
    "parent"
);

Related sample:  Loading subtasks on demand (branch loading)


Generally, the client side has no information about children of the displayed data items (as such children were not loaded from the server side).

To pass this information, you can use a special data property '$has_child' (can be changed using branch_loading_property) that indicates the number of the child elements for the task.

function check_children($row){
 global $gantt;
 $task_id = $row->get_value('id');
 $sql = "SELECT COUNT(id) AS has_children FROM gantt_tasks WHERE parent='{$task_id}'";
 $children = $gantt->sql->query($sql);
 
 $child = $gantt->sql->get_next($children);
 $children_qty = $child['has_children'];
 
 $row->set_userdata('$has_child',$children_qty);
}
$gantt->event->attach("beforeRender","check_children");

Related sample:  Loading subtasks on demand (branch loading)

Data format for dynamic loading

The format of data for dynamic loading is the following:

{
    "tasks":[
    {
        "id":13,
        "start_date":"2020-04-02 00:00:00",
        "duration":10,
        "text":"Task #1",
        "progress":0.2,
        "parent":12,
        "open":0,
        "$has_child":0
    },
    {
        "id":14,
        "start_date":"2020-04-04 00:00:00",
        "duration":4,
        "text":"Task #2",
        "progress":0.9,
        "parent":12,
        "open":0,
        "$has_child":4
    }],
 
    "links":[
        {"id":1,"source":1,"target":2,"type":"0"},
        {"id":2,"source":1,"target":3,"type":"0"},
        {"id":3,"source":1,"target":4,"type":"0"}
    ]
 
}

As you can see, it's the same JSON as the one used for regular data loading. To compare, check the Supported Data Formats article.

The only difference is the $has_child property which indicates whether a task will be displayed as a 'leaf' item (without the 'expand' toggle) or as an expandable node:

  • if the $has_child property is specified and contains a 'truthy' value (a non-zero number, true, a non-empty string, etc.), the item will be displayed with the expand/collapse toggle. On expanding the toggle, an Ajax request will be sent to the server;
  • if $has_child is not specified or contains a 'falsy' value (zero, false, NaN, undefined, empty string, null), the item will be displayed without toggle, as a task which has no child items.

If the request has the parent_id parameter, the response must contain children of the task with the specified id. If parent_id is not specified, the request must contain root level tasks:

ActionHTTP MethodURLResponse
load root level GET /loadUrl Dynamic loading format
load children on the task GET /loadUrl?parent_id=id Dynamic loading format

Loading tasks dynamically

You may implement dynamic loading of tasks so that new tasks to load after you scroll to the last visible task. Read details in the How to load tasks dynamically article.

Back to top