You can move events between two synchronized schedulers.
Agent-readable demo data
- Title
- Event Moving between Two Schedulers (JavaScript Scheduler) | DayPilot Pro for JavaScript Sandbox
- Tree
- DayPilot JavaScript Sandbox
- Catalog root
- Default
- Description
- You can move events between two synchronized schedulers.
Inline demo script 1
const dp = new DayPilot.Scheduler("dp1", {
cellWidth: 40,
startDate: "2026-01-01",
days: 365,
scale: "Day",
rowMarginBottom: 5,
timeHeaders: [
{groupBy: "Month"},
{groupBy: "Day", format: "d"}
],
treeEnabled: true,
rowHeaderWidth: 200,
resources: [
{ name: "Room A", id: "A", children: [{name: "Part 1", id: "A.1"}, {name: "Part 2", id: "A.2"}] },
{ name: "Room B", id: "B" },
{ name: "Room C", id: "C" },
{ name: "Room D", id: "D" },
{ name: "Room E", id: "E" },
{ name: "Room F", id: "F" },
{ name: "Room G", id: "G" },
{ name: "Room H", id: "H" },
{ name: "Room I", id: "I" },
{ name: "Room J", id: "J", children: [{name: "Part 1", id: "J.1"}, {name: "Part 2", id: "J.2"}] }
],
onEventMove: args => app.eventMove(dp, args),
onTimeRangeSelected: async args => {
const modal = await DayPilot.Modal.prompt("New event name:", "Event");
const name = modal.result;
dp.clearSelection();
if (!name) return;
dp.events.add(new DayPilot.Event({
start: args.start,
end: args.end,
id: DayPilot.guid(),
resource: args.resource,
text: name
}));
dp.message("Created");
},
allowEventOverlap: false,
onEventMoving: args => {
args.left.enabled = true;
args.left.html = args.e.start().toString();
},
dragOutAllowed: true,
height: 200
});
dp.init();
dp.scrollTo("2026-03-15");
const dp2 = new DayPilot.Scheduler("dp2", {
cellWidth: 40,
startDate: "2026-01-01",
days: 365,
scale: "Day",
timeHeaders: [
{groupBy: "Month"},
{groupBy: "Day", format: "d"}
],
treeEnabled: true,
rowHeaderWidth: 200,
resources: [
{ name: "Room A", id: "A", children: [{name: "Part 1", id: "A.1"}, {name: "Part 2", id: "A.2"}] },
{ name: "Room B", id: "B" },
{ name: "Room C", id: "C" },
{ name: "Room D", id: "D" },
{ name: "Room E", id: "E" },
{ name: "Room F", id: "F" },
{ name: "Room G", id: "G" },
{ name: "Room H", id: "H" },
{ name: "Room I", id: "I" },
{ name: "Room J", id: "J", children: [{name: "Part 1", id: "J.1"}, {name: "Part 2", id: "J.2"}] }
],
dragOutAllowed: true,
onEventMove: args => app.eventMove(dp2, args),
onEventMoving: args => {
args.left.enabled = true;
args.left.html = args.start.toString("MMMM d, yyyy @ h:mm tt");
},
height: 200,
});
dp2.init();
const app = {
init() {
this.synchronizeScrollbars();
this.loadEventData();
this.loadEventData2();
},
eventMove(target, args) {
const source = args.e.calendar;
if (target !== source) {
source.events.remove(args.e);
}
},
synchronizeScrollbars() {
// scrollbar synchronization
dp.nav.scroll.addEventListener("scroll", function () {
dp2.nav.scroll.scrollLeft = dp.nav.scroll.scrollLeft;
});
dp2.nav.scroll.addEventListener("scroll", function () {
dp.nav.scroll.scrollLeft = dp2.nav.scroll.scrollLeft;
});
},
loadEventData() {
const events = [];
for (let i = 0; i < 15; i++) {
const duration = Math.floor(Math.random() * 6) + 1; // 1 to 6
const durationDays = Math.floor(Math.random() * 6 + 2); // 2 to 7
const start = Math.floor(Math.random() * 6) + 2; // 2 to 7
const resId = String.fromCharCode(65 + i);
const event = {
start: new DayPilot.Date("2026-03-25T00:00:00").addDays(start),
end: new DayPilot.Date("2026-03-25T12:00:00").addDays(start).addDays(durationDays).addHours(duration),
id: DayPilot.guid(),
resource: resId,
text: `Event ${i + 1}`
};
events.push(event);
}
dp.update({events});
},
loadEventData2() {
const events = [
{
start: new DayPilot.Date("2026-03-20T00:00:00"),
end: new DayPilot.Date("2026-03-21T12:00:00"),
id: DayPilot.guid(),
resource: "A",
text: "Event 21",
bubbleHtml: "Testing bubble"
}
];
dp2.update({
events: events
});
}
};
app.init();