# JavaScript Gantt Chart | DayPilot Pro for JavaScript Sandbox

> Customize the component using [Gantt Chart UI Builder](https://builder.daypilot.org/gantt) and download a ready-to-run project. Read more about the [JavaScript Gantt Chart](https://javascript.daypilot.org/gantt/).

## Links

- Canonical HTML: /sandbox/gantt/index.html
- Source HTML folder: /sandbox/gantt/
- Catalog root: /sandbox/
- Catalog: /sandbox/llms.txt

## Source

### Inline demo script 1

```javascript
const gantt = new DayPilot.Gantt("gantt", {
            paddingDays: 2,
            columns: [
                {
                    title: "Name",
                    width: 50,
                    property: "text"
                },
                {
                    title: "Info",
                    width: 50,
                    property: "info"
                },
                {
                    title: "Duration",
                    width: 50
                }
            ],
            onBeforeRowHeaderRender: (args) => {
                const duration = gantt.tasks.businessDuration(args.task);
                const html = duration.toString("d") + "d " + duration.toString("h") + "h";
                args.row.columns[2].html = html;
            },
            onBeforeTaskRender: (args) => {
                // args.data.box.html = args.data.text;
            },
            onRowMoving: (args) => {
                //args.position = "forbidden";
            },
            onColumnResized: (args) => {
                console.log(args);
                console.log(gantt.columns);
            },
            contextMenuLink: new DayPilot.Menu({
                items: [
                    {
                        text: "Show link ID", onClick: (args) => {
                            DayPilot.Modal.alert("Link ID: " + args.source.data.id);
                        }
                    },
                    {
                        text: "Delete link", onClick: (args) => {
                            gantt.links.remove(args.source);
                        }
                    }
                ]
            }),
            contextMenuTask: new DayPilot.Menu({
                items: [
                    {
                        text: "Show task ID", onClick: (args) => {
                            DayPilot.Modal.alert("Task ID: " + args.source.id());
                        }
                    },
                    {
                        text: "Delete task", onClick: (args) => {
                            gantt.tasks.remove(args.source);
                        }
                    }
                ]
            }),
            contextMenuRow: new DayPilot.Menu({
                items: [
                    {
                        text: "Show task ID", onClick: (args) => {
                            DayPilot.Modal.alert("Task ID: " + args.source.id());
                        }
                    },
                    {
                        text: "Delete task", onClick: (args) => {
                            gantt.tasks.remove(args.source);
                        }
                    }
                ]
            }),
            onTaskClick: async (args) => {

                const completeLevels = [
                    {name: "Not started", id: 0},
                    {name: "In progress", id: 50},
                    {name: "Completed", id: 100}
                ];

                const form = [
                    {name: "Name", id: "text"},
                    {name: "Start", id: "start", type: "date"},
                    {name: "End", id: "end", type: "date"},
                    {name: "Complete", id: "complete", type: "select", options: completeLevels},
                    {name: "Info", id: "tags.info"}
                ];

                const modal = await DayPilot.Modal.form(form, args.task.data);
                if (modal.canceled) {
                    return;
                }

                gantt.tasks.update(modal.result);

            },
            onTaskDoubleClicked: (args) => {
                alert("Double-clicked: " + args.task.id());
                console.log(args);
            },
            onRowMove: (args) => {
                console.log(args);
            },
            onRowMoved: (args) => {
                console.log(args);
            },
            onLinkCreate: (args) => {
                console.log(args);
            },
            onRowDoubleClick: (args) => {
                console.log(args);
            },
            onRowSelect: (args) => {
                console.log(args);
            },
            onTaskRightClick: (args) => {
                console.log(args);
            },
            onTaskMove: (args) => {
                console.log("onTaskMove", args);
            },
            onTaskMoved: (args) => {
                console.log("onTaskMoved", args);
            },
            onTaskMoving: (args) => {
                console.log("onTaskMoving", args);
            },
            onRowExpand: (args) => {
                console.log("onRowExpand", args);
            },
            onRowCollapse: (args) => {
                console.log("onRowCollapse", args);
            },
        });
        gantt.init();

        const app = {
            loadData() {

                const tasks = [];
                const links = [];

                // generate and load sample tasks
                let start = DayPilot.Date.today();
                let last = null;
                for (let i = 0; i < 7; i++) {
                    const duration = Math.floor(Math.random() * 3) + 1 + 2; // 1 to 3
                    const end = start.addDays(duration);

                    const e = {
                        start: start,
                        end: end,
                        id: DayPilot.guid(),
                        text: "Task " + i,
                        tags: {
                            info: "info text"
                        },
                        children: [
                            {
                                start: start,
                                end: end,
                                id: DayPilot.guid(),
                                text: "Subtask 1",
                                complete: 100
                            },
                            {
                                start: start,
                                end: end,
                                id: DayPilot.guid(),
                                text: "Subtask 2",
                                complete: 50
                            },
                            {
                                start: end,
                                id: DayPilot.guid(),
                                text: "Milestone 1",
                                type: "Milestone"
                            }

                        ]
                    };

                    tasks.push(e);

                    if (last) {
                        links.push({
                            id: DayPilot.guid(),  // optional
                            from: last,
                            to: e.id,
                            type: "FinishToStart"
                        });
                    }
                    last = e.id;
                    start = end;

                }

                gantt.update({
                    tasks,
                    links
                });

            },
            init() {
                this.loadData();
            }
        };
        app.init();
```

