Agent-readable demo data

Title
Infinite Scrolling (JavaScript Scheduler) | DayPilot Pro for JavaScript Demo
Tree
DayPilot JavaScript Demo
Catalog root
Default
Description
Scroll horizontally to extend the timeline. Auto adjusts the buffer to the available width. Settings apply when changed. Read more about infinite scrolling.

Inline demo script 1

const dp = new DayPilot.Scheduler("dp", {
            startDate: "2026-10-01",
            scale: "Day",
            cellWidth: 40,
            timeHeaders: [
                {groupBy: "Month", format: "MMMM yyyy"},
                {groupBy: "Day", format: "d"}
            ],
            infiniteScrollingEnabled: "Auto",
            days: 300,
            infiniteScrollingStepDays: 70,
            infiniteScrollingMargin: 200,
            rowHeaderWidth: 180,
            heightSpec: "Fixed",
            height: 360,
            resources: Array.from({length: 12}, (_, i) => ({id: "R" + i, name: "Resource " + (i + 1)})),
            dynamicLoading: true,
            scrollDelayEvents: 0,
            eventMoveHandling: "Disabled",
            eventResizeHandling: "Disabled",
            timeRangeSelectedHandling: "Disabled",
            onScroll: (args) => {
                args.events = app.events(args.viewport);
                args.loaded();
            }
        });

        const app = {
            events(viewport) {
                const list = [];
                const origin = new DayPilot.Date("2026-01-01");
                const interval = 3;
                const first = Math.floor(new DayPilot.Duration(viewport.start.ticks - origin.ticks).totalDays() / interval) - 1;
                const last = Math.ceil(new DayPilot.Duration(viewport.end.ticks - origin.ticks).totalDays() / interval);
                for (let slot = first; slot <= last; slot++) {
                    for (let row = 0; row < dp.resources.length; row++) {
                        const from = origin.addDays(slot * interval + (row % 3));
                        list.push({
                            id: row + ":" + from.toString(),
                            resource: "R" + row,
                            start: from,
                            end: from.addDays(2),
                            text: ["Planning", "Delivery", "Review", "Preparation"][row % 4],
                            backColor: row % 2 ? "#dcfce7" : "#dbeafe",
                            barColor: row % 2 ? "#16a34a" : "#2563eb"
                        });
                    }
                }
                return list;
            },
            read() {
                const mode = document.getElementById("scrolling-mode").value;
                return {
                    infiniteScrollingEnabled: mode === "Auto" ? "Auto" : mode === "true",
                    days: Number(document.getElementById("range-days").value),
                    infiniteScrollingStepDays: Number(document.getElementById("step-days").value),
                    infiniteScrollingMargin: Number(document.getElementById("margin").value)
                };
            },
            apply() {
                const form = document.getElementById("infinite-settings");
                if (!form.reportValidity()) {
                    return;
                }
                const options = this.read();
                const anchor = dp.getViewport().start;
                const message = document.getElementById("settings-message");
                try {
                    if (!options.infiniteScrollingEnabled) {
                        options.startDate = anchor.getDatePart();
                    }
                    dp.update(options);
                    dp.scrollTo(anchor);
                    this.previous = options;
                    message.hidden = true;
                } catch (error) {
                    dp.update(this.previous);
                    dp.scrollTo(anchor);
                    message.textContent = error.message || String(error);
                    message.hidden = false;
                }
            },
            showFields() {
                const mode = document.getElementById("scrolling-mode").value;
                document.getElementById("manual-settings").hidden = mode === "Auto";
                document.getElementById("step-setting").hidden = mode === "false";
                document.getElementById("margin-setting").hidden = mode === "false";
                document.getElementById("settings-help").hidden = mode === "false";
            },
            scrollTo(date) {
                try {
                    dp.scrollTo(date);
                } catch (error) {
                    const message = document.getElementById("settings-message");
                    message.textContent = error.message || String(error);
                    message.hidden = false;
                }
            },
            init() {
                this.previous = this.read();
                const form = document.getElementById("infinite-settings");
                form.addEventListener("change", () => {
                    this.showFields();
                    this.apply();
                });
                form.addEventListener("submit", (event) => {
                    event.preventDefault();
                    this.apply();
                });
                for (const [id, date] of [
                    ["jan1", "2026-01-01"],
                    ["jun1", "2026-06-01"],
                    ["nov1", "2026-11-01"]
                ]) {
                    document.getElementById(id).addEventListener("click", () => this.scrollTo(date));
                }
                document
                    .getElementById("minus")
                    .addEventListener("click", () => this.scrollTo(dp.getViewport().start.addMonths(-1)));
                document
                    .getElementById("plus")
                    .addEventListener("click", () => this.scrollTo(dp.getViewport().start.addMonths(1)));
                document.getElementById("today").addEventListener("click", () => this.scrollTo(DayPilot.Date.today()));
                document.getElementById("scroll-date-go").addEventListener("click", () => {
                    const field = document.getElementById("scroll-date");
                    if (field.value && field.reportValidity()) {
                        this.scrollTo(field.value);
                    }
                });
            }
        };
        // Dynamic loading calls app.events() during the initial render.
        dp.init();

        app.init();