external drag preview

DayPilot JavaScript Scheduler supports drag and drop from an external source (from outside of the Scheduler component).

This feature is useful for implementing the following scenario:

  • The Scheduler shows the current time schedule.

  • You need to display a separate list of events that are not scheduled yet. 

  • The unscheduled events can be dragged to the calendar/scheduler.

Activating the External Items

You need to activate the items in the list using DayPilot.Scheduler.makeDraggable() method:

<div style="float:left; width: 150px;">
  Drag items from this list to the scheduler:
  <ul id="external">
      <li data-id="123" data-duration="1800"><span style="cursor:move">Item #123 (30 minutes)</span></li>
      <li data-id="124" data-duration="3600"><span style="cursor:move">Item #124 (60 minutes)</span></li>
  </ul>
</div>

<script type="text/javascript">
function makeDraggable() {
  var parent = document.getElementById("external");
  var items = parent.getElementsByTagName("li");
  for (var i = 0; i < items.length; i++) {
      var e = items[i];
      var item = {
          element: e,
          data: {
            id: e.getAttribute("data-id"),
            text: e.innerText,
            duration: e.getAttribute("data-duration")
          }
      };
      DayPilot.Scheduler.makeDraggable(item);
  }
}
</script>

Item properties:

  • element (object) - the element to be removed on drop

  • id (string) - event ID

  • text (string) - event text

  • duration (integer) - event duration in seconds

  • keepElement (boolean) - set to true if the original element should not be removed from DOM on drop

  • externalCssClass (string) - CSS class that will be applied to the moving shadow (when it is outside of the Scheduler)

  • externalHtml (string) - HTML that will be added to the moving shadow (when it is outside of the Scheduler)

The event id, text, and duration will be passed to onEventMove event handler on drop.

external drag accepted

In this example, a successful drop places Pump service from 10:00 to 12:00 and the application removes it from the unscheduled list. The other jobs remain available.

After dropping the object the standard EventMove event is triggered (handling specified by eventMoveHandling). You can detect the external source by checking the value of args.external property in onEventMove.

Touch Support

The DayPilot.Scheduler.makeDraggable() method is compatible with touch devices and it is possible to move the item using touch dragging.

JavaScript Tutorials

API: events.list, resources.

The examples create one unscheduled task that can be dropped into a room and time slot. The framework owns an empty source container; application code appends the draggable child so DayPilot can remove that child after a successful drop.

The framework examples use DayPilot Pro. For installation, see the Angular, React or Vue Scheduler guide.

Angular

Use @ViewChild to access the source container and call makeDraggable() in ngAfterViewInit(). ngOnDestroy() stops dragging and clears any remaining child.

import {Component, ViewChild, ElementRef, AfterViewInit, OnDestroy} from "@angular/core";
import {DayPilot, DayPilotModule} from "daypilot-pro-angular";

@Component({
  selector: "app-scheduler-example",
  standalone: true,
  imports: [DayPilotModule],
  template: `
    <div #sourceHost></div>
    <daypilot-scheduler [config]="config"></daypilot-scheduler>
  `
})
export class SchedulerExampleComponent implements AfterViewInit, OnDestroy {
  @ViewChild("sourceHost") sourceHost!: ElementRef<HTMLDivElement>;
  config: DayPilot.SchedulerConfig = {
    startDate: "2026-11-01",
    days: 30,
    scale: "Day",
    timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "d"}],
    resources: [{id: "A", name: "Room A"}, {id: "B", name: "Room B"}],
    events: [{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}]
  };

  ngAfterViewInit() {
    const item = document.createElement("div");
    item.textContent = "Unscheduled task";
    item.style.cssText = "padding: 10px; margin: 8px 0; border: 1px solid #888; cursor: move;";
    this.sourceHost.nativeElement.appendChild(item);
    DayPilot.Scheduler.makeDraggable({element: item, data: {id: "unscheduled", text: "Unscheduled task", duration: 86400}});
  }
  ngOnDestroy() { DayPilot.Scheduler.stopDragging(); this.sourceHost.nativeElement.replaceChildren(); }
}

Angular Tutorials

React

Create the draggable child inside useEffect after the container ref is available. Return cleanup that stops dragging and removes the child when the effect is disposed.

import React, {useRef, useEffect} from "react";
import {DayPilot, DayPilotScheduler} from "daypilot-pro-react";

export default function SchedulerExample() {
  const sourceHost = useRef(null);
  useEffect(() => {
    const item = document.createElement("div");
    item.textContent = "Unscheduled task";
    item.style.cssText = "padding: 10px; margin: 8px 0; border: 1px solid #888; cursor: move;";
    sourceHost.current.appendChild(item);
    DayPilot.Scheduler.makeDraggable({element: item, data: {id: "unscheduled", text: "Unscheduled task", duration: 86400}});
    return () => { DayPilot.Scheduler.stopDragging(); item.remove(); };
  }, []);

  return <div>
    <div ref={sourceHost} />

    <DayPilotScheduler
      startDate={"2026-11-01"}
      days={30}
      scale={"Day"}
      timeHeaders={[{groupBy: "Month"}, {groupBy: "Day", format: "d"}]}
      resources={[{id: "A", name: "Room A"}, {id: "B", name: "Room B"}]}
      events={[{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}]}
    />
  </div>;
}

React Tutorials

Vue

Initialize the draggable child in onMounted() using the source container's template ref. onUnmounted() stops dragging and removes any remaining child.

<script setup>
import {ref, onMounted, onUnmounted} from "vue";
import {DayPilot, DayPilotScheduler} from "daypilot-pro-vue";

const sourceHost = ref(null);
const startDate = "2026-11-01";
const days = 30;
const scale = "Day";
const timeHeaders = [{groupBy: "Month"}, {groupBy: "Day", format: "d"}];
const resources = [{id: "A", name: "Room A"}, {id: "B", name: "Room B"}];
const events = [{id: 1, text: "Planning", resource: "A", start: "2026-11-03", end: "2026-11-06"}, {id: 2, text: "Delivery", resource: "B", start: "2026-11-08", end: "2026-11-11"}];

let item;
onMounted(() => {
  item = document.createElement("div");
    item.textContent = "Unscheduled task";
    item.style.cssText = "padding: 10px; margin: 8px 0; border: 1px solid #888; cursor: move;";
    sourceHost.value.appendChild(item);
    DayPilot.Scheduler.makeDraggable({element: item, data: {id: "unscheduled", text: "Unscheduled task", duration: 86400}});
});
onUnmounted(() => { DayPilot.Scheduler.stopDragging(); item?.remove(); });
</script>

<template>
  <div>
    <div ref="sourceHost"></div>

    <DayPilotScheduler
      :startDate="startDate"
      :days="days"
      :scale="scale"
      :timeHeaders="timeHeaders"
      :resources="resources"
      :events="events"
    />
  </div>
</template>

Vue Tutorials

vue tutorial queue 2028

The Vue Scheduler: Queue of Unscheduled Tasks tutorial shows how to use the Queue component to display a list of tasks that can be dragged to the Vue Scheduler.

  • The queue uses the same item styling as the Vue Scheduler component.

  • The items can be moved using drag and drop in both directions (to and from the Vue Scheduler).

  • The queue is ordered and users can change the order by dragging the items.

AngularJS

In AngularJS, it's possible to activate items using a simple directive (daypilot-draggable):

HTML

<ul>
    <li daypilot-draggable data-id="1" data-duration="1800">Draggable item #1</li>
    <li daypilot-draggable data-id="2" data-duration="3600">Draggable item #2</li>
</ul>

JavaScript

app.directive("daypilotDraggable", function(){
    return {
        link: function(scope, element, attributes){
            var el = element[0];
            el.style.cursor = "move";
            DayPilot.Scheduler.makeDraggable({
                element: el,
                id: el.getAttribute("data-id"),
                duration: el.getAttribute("data-duration"),
                text: el.innerText
            });

        }
    };
});

ASP.NET WebForms

Demo:

Availability

Availability of this feature in DayPilot editions:

ProductLitePro
DayPilot for JavaScript
DayPilot for ASP.NET WebForms
DayPilot for ASP.NET MVC
DayPilot for Java