# External Drag and Drop (JavaScript Gantt Chart) | DayPilot Pro for JavaScript Demo

> You can [drag tasks from an external list](https://doc.daypilot.org/gantt/external-drag-and-drop-of-tasks/) to the Gantt chart.

## Links

- Canonical HTML: /demo/gantt/external.html
- Source HTML folder: /demo/gantt/
- Catalog root: /demo/
- Catalog: /demo/llms.txt

## Source

### Inline demo script 1

```javascript
const dp = new DayPilot.Gantt("dp", {
            startDate: DayPilot.Date.today().addDays(-1),
            days: 60,
            columns: [
                {title: "Name", width: 50, property: "text"},
                {title: "Info", width: 50, property: "info"},
                {title: "Duration", width: 50}
            ],
            onBeforeRowHeaderRender: args => {
                const duration = args.task.duration();
                const html = duration.toString("d") + "d " + duration.toString("h") + "h";
                args.row.columns[2].html = html;
            },
            contextMenu: new DayPilot.Menu({
                items: [
                    {
                        text: "Show task ID", onClick: args => {
                            DayPilot.Modal.alert("Task ID: " + args.source.id());
                        }
                    },
                    {
                        text: "Delete task", onClick: args => {
                            dp.tasks.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 => {
                            dp.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 => {
                            dp.tasks.remove(args.source);
                        }
                    }
                ]
            }),
        });
        dp.init();

        const app = {
            init() {
                this.makeDraggable();
                this.registerDropTarget();
                this.loadData();
            },
            loadData() {
                const tasks = [];
                const links = [];

                let start = DayPilot.Date.today();
                let last = null;
                for (let i = 0; i < 5; i++) {
                    const duration = Math.floor(Math.random() * 3) + 1; // 1 to 3
                    const end = start.addDays(duration);

                    const task = {
                        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: Math.floor(Math.random() * 101) // 0 to 100
                            },
                            {
                                start: start,
                                end: end,
                                id: DayPilot.guid(),
                                text: "Subtask 2",
                                complete: Math.floor(Math.random() * 101) // 0 to 100
                            },
                            {
                                start: end,
                                id: DayPilot.guid(),
                                text: "Milestone 1",
                                type: "Milestone"
                            }

                        ]
                    };

                    tasks.push(task);

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

                }
                dp.update({tasks, links});
            },
            makeDraggable() {
                // activate items as source
                const parent = document.getElementById("external");
                const items = parent.getElementsByTagName("li");
                for (let i = 0; i < items.length; i++) {
                    const e = items[i];
                    const item = {
                        element: e,
                        remove: e,
                        data: {
                            id: e.getAttribute("data-id"),
                            text: e.innerText,
                            duration: DayPilot.Duration.hours(e.getAttribute("data-duration")),  // hours
                            box: {
                                barColor: "#a12424",
                                barBackColor: "#b88888",
                            }
                        },
                        onDragStart: (args) => {
                            const e = args.options.element;
                            e.style.opacity = "0.5";
                        },
                        onDrop: (args) => {
                            const e = args.options.element;
                            e.style.opacity = "";
                        },
                    };
                    DayPilot.Gantt.makeDraggable(item);
                }
            },
            registerDropTarget() {
                // activate as target
                DayPilot.Gantt.registerDropTarget({
                    element: document.getElementById("queue"),
                    onDrop: args => {
                        const parent = document.getElementById("external");
                        const li = document.createElement("li");
                        li.setAttribute("data-duration", args.task.duration().totalHours());
                        li.setAttribute("data-id", args.task.id());
                        li.style.cursor = "move";
                        li.innerText = args.task.text();
                        parent.appendChild(li);

                        app.makeDraggable();

                        dp.tasks.remove(args.task);
                        document.getElementById("queue").style.backgroundColor = "";
                    },
                    onDragOver: args => {
                        document.getElementById("queue").style.backgroundColor = "#f8f8f8";
                    },
                    onDragLeave: args => {
                        document.getElementById("queue").style.backgroundColor = "";
                    }
                });
            }
        };
        app.init();
```

