# 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](https://www.telerik.com/kendo-angular-ui-develop/components/utils/draganddrop) utility to move items from ListView to the Scheduler. To create new Scheduler events, you can use the [built-in editing directive](https://www.telerik.com/kendo-angular-ui-develop/components/scheduler/editing#automatic-editing-configuration), [reactive forms editing](https://www.telerik.com/kendo-angular-ui-develop/components/scheduler/editing/editing-reactive-forms), 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.

[Demo Source](https://demos.telerik.com/kendo-angular-ui/demos/scheduler/editing/external-drag-and-drop/source.txt)

## Configuring the Drag and Drop

To enable users to drag and drop tasks between the ListView and Scheduler components:

1. Wrap both components inside a custom container and apply the `kendoDragTargetContainer` and `kendoDropTargetContainer` directives to it.

   ```html
   <div
       #dragWrapper
       kendoDragTargetContainer
       ...>
       <delivery-list [tasks]="tasks">
       </delivery-list>
   </div>
   <div
       #dropWrapper
       kendoDropTargetContainer
   >
       <kendo-scheduler
           #scheduler
           [kendoSchedulerBinding]="events"
           ...>
       </kendo-scheduler>
   </div>
   ```

2. Use [`dragTargetFilter`](https://www.telerik.com/kendo-angular-ui-develop/components/utils/api/dragtargetcontainerdirective#dragtargetfilter) to specify the draggable element targets and [`dropTargetFilter`](https://www.telerik.com/kendo-angular-ui-develop/components/utils/api/droptargetcontainerdirective#droptargetfilter) to configure the drop targets. Then, handle the Kendo UI for Angular Drag and Drop [events](https://www.telerik.com/kendo-angular-ui-develop/components/utils/draganddrop/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>
   ```

3. Use the [`addEvent` method](https://www.telerik.com/kendo-angular-ui-develop/components/scheduler/api/schedulercomponent#addevent) 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 the [`kendoSchedulerTimeSlotTemplate`](https://www.telerik.com/kendo-angular-ui-develop/components/scheduler/api/timeslottemplatedirective).

   ```html
   <div
       kendoDropTargetContainer
       (onDrop)="onDrop($event, scheduler)"
       ...>
       <kendo-scheduler
           #scheduler
           [kendoSchedulerBinding]="events"
           [kendoSchedulerReactiveEditing]="createFormGroup"
           ...>
           <ng-template kendoSchedulerTimeSlotTemplate let-date="date" let-resources="resources">
               
               <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>
   ```

   ```ts
   public 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();
   }
   ```

4. To inform the `dragTargetContainer` about changes in its content resulting from the creation of a new event, obtain the reference of the `dragTargetContainer` directive and call the [`notify`](https://www.telerik.com/kendo-angular-ui-develop/components/utils/api/dragtargetcontainerdirective#notify) method 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();
   }
   ```

5. (Optional) To enable the drag-and-drop of events across multiple views inside the Scheduler, handle the built-in [`navigate`](https://www.telerik.com/kendo-angular-ui-develop/components/scheduler/api/schedulercomponent#navigate) event of the component and inform the `DropTargetContainer` that its content has changed using the built-in [`notify()`](https://www.telerik.com/kendo-angular-ui-develop/components/utils/api/droptargetcontainerdirective#notify) method.

   ```ts
   public 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();
           });
       }
   }
   ```

## Suggested Links

* [Angular Scheduler Overview](https://www.telerik.com/kendo-angular-ui-develop/components/scheduler)
* [API Index of the Kendo UI for Angular Scheduler](https://www.telerik.com/kendo-angular-ui-develop/components/scheduler/api)
* [API Index of the Kendo UI for Angular ListView](https://www.telerik.com/kendo-angular-ui-develop/components/listview/api)
* [Kendo UI for Angular Drag and Drop Overview](https://www.telerik.com/kendo-angular-ui-develop/components/utils/draganddrop)
