Drag & Drop
Without this plugin the scheduler is read-only at the pointer level: events render, but they cannot be moved, resized, or created by dragging. Installing it turns the timeline into an editable surface.
Installation
npm install @dayflow-scheduler/plugin-dragUsage
Pass createDragPlugin() to the plugins array. The factory takes a required config object: pass {} to accept the defaults.
import { useSchedulerApp } from '@dayflow-scheduler/react';
import { createDragPlugin } from '@dayflow-scheduler/plugin-drag';
const app = useSchedulerApp({
resources,
events,
plugins: [
createDragPlugin({
onEventDrop: (updated, original) => api.reschedule(updated, original),
onEventResize: updated => api.resize(updated),
}),
],
});import { useSchedulerApp } from '@dayflow-scheduler/vue';
import { createDragPlugin } from '@dayflow-scheduler/plugin-drag';
const app = useSchedulerApp({
resources,
events,
plugins: [
createDragPlugin({
onEventDrop: (updated, original) => api.reschedule(updated, original),
onEventResize: updated => api.resize(updated),
}),
],
});import { SchedulerApp } from '@dayflow-scheduler/angular';
import { createDragPlugin } from '@dayflow-scheduler/plugin-drag';
app = new SchedulerApp({
resources: this.resources,
events: this.events,
plugins: [
createDragPlugin({
onEventDrop: (updated, original) => this.api.reschedule(updated, original),
onEventResize: updated => this.api.resize(updated),
}),
],
});import { createSchedulerApp } from '@dayflow-scheduler/svelte';
import { createDragPlugin } from '@dayflow-scheduler/plugin-drag';
const app = createSchedulerApp({
resources,
events,
plugins: [
createDragPlugin({
onEventDrop: (updated, original) => api.reschedule(updated, original),
onEventResize: updated => api.resize(updated),
}),
],
});Drag stays off until the license verifies
The plugin installs with all interactions disabled and enables them once license verification resolves. If dragging never becomes available, check the console for a license error; see Registry Access & License.
Options
| Option | Type | Default | Description |
|---|---|---|---|
enableDrag | boolean | true | Allow moving events by dragging. |
enableResize | boolean | true | Allow changing event duration by dragging an edge. |
enableCreate | boolean | true | Allow creating events by dragging on an empty part of a row. |
supportedViews | (ViewType | string)[] | ['resource', 'timeline'] | View types where dragging is active. See ViewType. |
onEventDrop | (updated, original) => void | - | Fired after an event is moved. |
onEventResize | (updated, original) => void | - | Fired after an event is resized. |
Turn individual interactions off rather than removing the plugin when you only want part of the behavior:
createDragPlugin({ enableCreate: false });Callbacks
Both callbacks receive two SchedulerEvent objects: updated is the event after the interaction, original the event before. That makes it easy to send a diff or roll back on failure:
createDragPlugin({
onEventDrop: async (updated, original) => {
try {
await api.updateEvent(updated);
} catch {
app.updateEvent(original.id, original);
}
},
});Plugin callbacks vs app callbacks
onEventDrop and onEventResize fire only for pointer interactions.
App-level
callbacks.onEventUpdate
fires for every update, including programmatic ones, with a source of
'drag' or 'resize'. Use the plugin callbacks for drag-specific UX, and the
app callbacks for persistence.
ViewType
supportedViews accepts ViewType values or the equivalent strings:
| Value | String | Description |
|---|---|---|
ViewType.RESOURCE | 'resource' | The resource (row-based) view. |
ViewType.TIMELINE | 'timeline' | The timeline (Gantt-style) view. |
import { ViewType } from '@dayflow-scheduler/core';
createDragPlugin({ supportedViews: [ViewType.RESOURCE] });Snapping and Time Rounding
Snapping is derived from the active view's cell width, not from the plugin. Adjust it by changing the per-view widths: a smaller hourWidth snaps coarser, a larger one snaps finer:
views: [createDayView({ hourWidth: 120 })],See Views.
Excluding Events from Dragging
Individual events and whole resources can opt out without disabling the plugin:
const events = [{ id: 'locked', title: 'Frozen', readOnly: true /* … */ }];
const resources = [{ id: 'archive', name: 'Archive', readOnly: true }];For an app-wide switch, use Read-only Mode.
Related Documentation
- Events: the event model these callbacks receive.
- Read-only Mode: disabling mutation UI globally or per event.
- Keyboard Shortcuts: keyboard equivalents for the same actions.