Hello @Joker,
I am sending you a workaround for your issue that you can use until there is no level parameter left in the gantt.templates.grid_indent
template.
This demo shows how to create a custom column in DHTMLX Gantt where each indentation level has its own background color. Here’s how it’s done:
1. Define Custom Colors for Each Task
We store color mappings in a taskColors
object:
const taskColors = {
1: "yellow",
2: "greenyellow",
3: "cyan",
4: "#ebbee9",
};
If a color isn’t defined for a task, we assign a random one using:
function getOrAssignTaskColor(taskId) {
if (!taskColors[taskId]) {
taskColors[taskId] = getRandomRgbColor();
injectRowColorStyles(); // re-render styles
}
return taskColors[taskId];
}
2. Apply Row Background Colors
Using gantt.templates.grid_row_class, we assign a unique class to each row based on the task ID:
gantt.templates.grid_row_class = function (start, end, task) {
return `row-color-${task.id}`;
};
Then we inject dynamic CSS styles into the document head:
function injectRowColorStyles() {
const rules = Object.entries(taskColors).map(([id, color]) => `
.gantt_row.row-color-${id} .gantt_tree_content,
.gantt_row.row-color-${id} .gantt_cell {
background-color: ${color};
}
`).join("\n");
const styleEl = document.getElementById("gantt-color-styles") || document.createElement("style");
styleEl.id = "gantt-color-styles";
styleEl.innerHTML = rules;
document.head.appendChild(styleEl);
}
We call this once when Gantt is ready, and whenever a new color is generated:
gantt.attachEvent("onGanttReady", function () {
injectRowColorStyles();
});
3. Render Custom Indentation and Toggle Button
In the first column (color_indent_column), we use a custom template function:
template: function (task) {
const ancestors = [];
gantt.eachParent((parent) => ancestors.push(parent.id), task.id);
const level = task.$level || 0;
const parts = [];
for (let i = 0; i < level; i++) {
const ancestorIndex = ancestors.length - i - 1;
const ancestorId = ancestors[ancestorIndex] || task.id;
const color = getOrAssignTaskColor(ancestorId);
parts.push(`<span class="indent-block" style="background-color: ${color};"></span>`);
}
if (gantt.hasChild(task.id)) {
const isOpen = task.$open;
const icon = isOpen ? "−" : "+";
const btnColor = getOrAssignTaskColor(task.id);
parts.push(`
<span class="toggle-btn" data-task-id=${task.id} style="background-color: ${btnColor};">
${icon}
</span>
`);
}
return `<div class="color-indent-column">${parts.join("")}</div>`;
}
This logic:
- Collects the list of ancestor tasks.
- For each level, renders a colored .indent-block.
- Adds a colored toggle button for tasks with children.
4. Handle Task Open/Close
Instead of attaching event listeners manually, we intercept task clicks:
gantt.attachEvent("onTaskClick", function (id, e) {
const target = e.target;
if (target.closest(".toggle-btn")) {
const task = gantt.getTask(id);
task.$open ? gantt.close(id) : gantt.open(id);
return false; // prevent default toggle
}
return true;
});
5. Support Newly Added Tasks
When a user adds a task (via the “+” button in the header), we ensure it gets a color:
gantt.attachEvent("onAfterTaskAdd", function (id) {
getOrAssignTaskColor(id);
});
Please check the code snippet: DHTMLX - Gantt. Grid indent styles like in Primavera.
Let me know if this resolves your issue.
Best regards,
Valeria Ivashkevich
Support Engineer