Drag and Drop between ListView and Scheduler
With drag and drop scheduling, you enable users to seamlessly create new Scheduler events by dragging items from external UI components and dropping them into a selected time slot.
To demonstrate the drag and drop scheduling capabilities of the Scheduler component, this article shows how to use the Kendo UI for Angular Drag and Drop utility to move items from ListView to the Scheduler. To create new Scheduler events, you can use the built-in editing directive, reactive forms editing, or direct adding of items to your events collection.
The following example demonstrates how to drag and drop items from the ListView to the Scheduler and create events.
Configuring the Drag and Drop
To enable users to drag and drop tasks between the ListView and Scheduler components:
-
Wrap both components inside a custom container and apply the
kendoDragTargetContainerandkendoDropTargetContainerdirectives to it.html<div #dragWrapper kendoDragTargetContainer ...> <delivery-list [tasks]="tasks"> </delivery-list> </div> <div #dropWrapper kendoDropTargetContainer > <kendo-scheduler #scheduler [kendoSchedulerBinding]="events" ...> </kendo-scheduler> </div> -
Use
dragTargetFilterto specify the draggable element targets anddropTargetFilterto configure the drop targets. Then, handle the Kendo UI for Angular Drag and Drop events, to open the event editing dialog and create a new event.html<div kendoDragTargetContainer dragTargetFilter=".k-listview-item" (onDrag)="onDrag($event)" (onDragStart)="onDragStart($event)" ...> <delivery-list [tasks]="tasks"> </delivery-list> </div> <div kendoDropTargetContainer dropTargetFilter=".drop-zone" (onDrop)="onDrop($event, scheduler)" (onDragLeave)="onDragLeave($event)" > <kendo-scheduler #scheduler [kendoSchedulerBinding]="events" ...> </kendo-scheduler> </div> -
Use the
addEventmethod of the Scheduler to open the event editing dialog and create a new event when a task is dropped. To get the specific time and resource of the slot, use thekendoSchedulerTimeSlotTemplate.html<div kendoDropTargetContainer (onDrop)="onDrop($event, scheduler)" ...> <kendo-scheduler #scheduler [kendoSchedulerBinding]="events" [kendoSchedulerReactiveEditing]="createFormGroup" ...> <ng-template kendoSchedulerTimeSlotTemplate let-date="date" let-resources="resources"> <!-- Store slot metadata so onDrop can create the event at the selected time and resource. --> <div class="drop-zone"> <div class="slotDate" [attr.allDay]="false" [attr.resourceId]="resources[0].value" [attr.slotDate]="date.getTime()" ></div> </div> </ng-template> </kendo-scheduler> </div>tspublic onDrop(ev: DropTargetEvent, scheduler: SchedulerComponent): void { if (this.isDropValid && this.currentDropZone) { const slotDateEl = this.currentDropZone.querySelector('.slotDate'); const slotDateValue = slotDateEl?.getAttribute('slotDate'); const resourceIdValue = slotDateEl?.getAttribute('resourceId'); if (slotDateValue === null || resourceIdValue === null) { this.clearHighlight(); return; } const slotDate = Number(slotDateValue); const resourceId = Number(resourceIdValue); if (Number.isNaN(slotDate) || Number.isNaN(resourceId)) { this.clearHighlight(); return; } const startDate = new Date(slotDate); const endDate = new Date(startDate.getTime() + 30 * 60000); // Convert the slot metadata to the event form's expected values. const isTaskAllDay: boolean = slotDateEl.getAttribute('allDay') === 'true'; const group = this.formBuilder.group({ id: this.getNextId(), start: [startDate, Validators.required], end: [endDate, Validators.required], startTimezone: new FormControl(), endTimezone: new FormControl(), isAllDay: isTaskAllDay, title: new FormControl(`${this.currentData.address} ${this.currentData.date}`), description: new FormControl(this.currentData.orderNumber), recurrenceRule: new FormControl(), recurrenceId: new FormControl(), recurrenceExceptions: new FormControl(), // Convert the resource attribute string to the numeric event field. employeeId: resourceId, }); // Pass the form group to addEvent to open the Scheduler editing dialog. scheduler.addEvent(group); } this.clearHighlight(); } -
To inform the
dragTargetContainerabout changes in its content resulting from the creation of a new event, obtain the reference of thedragTargetContainerdirective and call thenotifymethod from the directive to refresh the view.ts@ViewChild('dragWrapper', { read: DragTargetContainerDirective }) public dragTargetContainer: DragTargetContainerDirective; public onSave(): void { ... // Refresh the ListView drag targets after the task is removed. this.dragTargetContainer.notify(); } -
(Optional) To enable the drag-and-drop of events across multiple views inside the Scheduler, handle the built-in
navigateevent of the component and inform theDropTargetContainerthat its content has changed using the built-innotify()method.tspublic onNavigate(e: NavigateEvent): void { if (e.action.type === 'view-change') { // Wait for the Scheduler view to render before refreshing drop targets. setTimeout(() => { this.dropTargetContainer.notify(); }); } }