Task Management
ApexGantt exposes a programmatic CRUD API for adding, updating, deleting, and re-parenting tasks after the chart has rendered. Every mutation method is recorded in the undo history, so users can reverse any change without extra wiring on your part.
Adding tasks
Use addTask(input, options?) to insert a new task and trigger a re-render.
const gantt = new ApexGantt(document.querySelector('#chart'), { series: [] })
gantt.render()
// Add a top-level task
gantt.addTask({
id: 'review',
name: 'Review',
startTime: '2024-08-01',
endTime: '2024-08-05'
})
To place a task inside an existing parent, pass its id in the second argument:
// Insert as a child of an existing task
gantt.addTask(
{
id: 'sub-1',
name: 'Subtask',
startTime: '2024-08-01',
endTime: '2024-08-03'
},
{ parentId: 'review-phase' }
)
What to expect:
- The method returns the inserted
Taskobject on success. - It returns
nullif abeforeTaskAddlifecycle hook cancelled the insertion. - It throws if the supplied
idalready exists in the chart.
Updating tasks
Use updateTask(taskId, updatedTask) to apply a partial update to an existing task. You only need to supply the fields you want to change; everything else is left untouched.
// Mark a task as complete
gantt.updateTask('task-3', { progress: 100 })
// Shift the scheduled dates
gantt.updateTask('task-3', { startTime: '2024-09-01', endTime: '2024-09-15' })
// Rename the task
gantt.updateTask('task-3', { name: 'Final Review' })
The chart updates the relevant rows without performing a full re-render, so the operation is efficient even for large task trees.
updateTask throws if the taskId does not match any task in the current dataset. Validate the id before calling if the source is dynamic.
Deleting tasks
Use deleteTask(taskId, options?) to remove a task and re-render.
// Remove a leaf task (no children)
gantt.deleteTask('task-5')
The method returns true when the task is removed, or false when a beforeTaskDelete hook cancelled the operation.
Cascade modes
When a task has children, you must decide what happens to them. Pass a cascade option to control this.
| Mode | Behavior | When to use |
|---|---|---|
'forbid' (default) | Throws if the task has children | Prevents accidental bulk deletion |
'children' | Deletes the task and all its descendants in one undoable transaction | Removing an entire phase or subtree |
'orphan' | Moves the task's immediate children up to the deleted task's parent (or root), then removes the task | Flattening a hierarchy without losing work |
// Remove a parent and all its descendants
gantt.deleteTask('phase-1', { cascade: 'children' })
// Remove a parent but keep its children (they move up one level)
gantt.deleteTask('phase-1', { cascade: 'orphan' })
Any dependency edges that referenced the deleted task are removed in the same transaction. You do not need to clean up arrows manually.
Moving tasks (re-parenting)
Use moveTask(taskId, options?) to change a task's parent without altering its other properties.
// Move task-5 under a different phase
gantt.moveTask('task-5', { newParentId: 'phase-2' })
// Promote task-5 to the root level
gantt.moveTask('task-5', { newParentId: null })
Pass newParentId: null to move a task to the root of the hierarchy.
The operation is recorded in the undo history. If the move would create a cycle (for example, moving a parent into one of its own descendants), moveTask throws rather than producing an invalid tree.
Milestones
Set type: 'milestone' on a task to render it as a diamond on the timeline instead of a bar. Milestones represent a point in time rather than a duration, so you can set startTime and endTime to the same date.
gantt.addTask({
id: 'go-live',
name: 'Go Live',
type: 'milestone',
startTime: '2024-09-30',
endTime: '2024-09-30'
})
The three task type values are:
'task'(default): a standard bar spanning the duration.'milestone': a diamond rendered at a single date.'summary': an auto-computed rollup bar. ApexGantt sets this automatically for rows that have children; you rarely need to set it manually.
You can also update an existing task's type:
gantt.updateTask('go-live', { type: 'milestone' })
Lifecycle hooks
Lifecycle hooks let you validate or cancel CRUD operations before they take effect. Register them in the GanttUserOptions when you construct the chart.
const gantt = new ApexGantt(document.querySelector('#chart'), {
series: tasks,
beforeTaskAdd: ({ task }) => {
// Reject tasks without a name
if (!task.name || task.name.trim() === '') {
alert('A task must have a name.')
return false
}
},
beforeTaskDelete: ({ task }) => {
// Ask the user before deleting an in-progress task
if (task.progress > 0 && task.progress < 100) {
return confirm(`"${task.name}" is still in progress. Delete anyway?`)
}
},
beforeTaskUpdate: ({ updates }) => {
// Reject out-of-range progress values
if (updates.progress !== undefined && updates.progress > 100) {
return false
}
},
beforeTaskMove: ({ taskId, newParentId }) => {
// Prevent moving tasks into a locked phase
if (lockedPhaseIds.has(newParentId)) {
return false
}
}
})
How hooks work:
- Return
false(or a promise that resolves tofalse) to cancel the operation. The chart state does not change and nothing is written to the undo history. - Return
true,undefined, or anything other thanfalseto allow the operation to proceed. - All hooks can be
async. ApexGantt awaits the return value before continuing.
The context object passed to each hook contains the relevant task data. For beforeTaskAdd this is the input you provided. For beforeTaskDelete and beforeTaskMove this includes the current task from the chart's data. For beforeTaskUpdate this includes taskId and the partial updates object.
Selection API
ApexGantt includes a selection API for reading and controlling which tasks are highlighted. Enable it with the enableSelection option:
const gantt = new ApexGantt(document.querySelector('#chart'), {
series: tasks,
enableSelection: true
})
gantt.render()
Then use these methods at any point after rendering:
// Read the currently selected task ids
const selected = gantt.getSelectedTasks()
console.log(selected) // ['task-1', 'task-3']
// Programmatically select specific tasks
gantt.setSelectedTasks(['task-1', 'task-3'])
// Clear all selections
gantt.clearSelection()
setSelectedTasks is useful when you want to sync the chart's selection with an external list or table. For example, if a user clicks a task name in a sidebar, call setSelectedTasks with that id to highlight the corresponding row in the chart.
Related
- Methods reference for the complete API surface.
- Options reference for
enableSelection, hook signatures, and all configuration fields.