0
votes

I'm trying to create a calendar in Angular for a personal project. I have a table with a div for each day of the month and inside this div I have my appointments. What I want to do is be able to drag and drop my appointment from a day to another, I try with the angular cdk drag & drop but can't have something working.

Here is a cell of my table:

<div #dayCell class="day-cell" cdkDropList (cdkDropListDropped)="drop($event)">
  <div>{{day.getDate()}}</div>
  <div class="schedule-wrapper full-width">
    <div cdkDrag *ngFor="let schedule of schedules" class="schedule" [style.width.px]="getScheduleWidth(schedule)">
      <div class="schedule-details">
        <div class="schedule-text">{{schedule.title}}</div>
      </div>
    </div>
  </div>
</div>

in the drop function I add a console log of the day used in the cell, when I drag my appointment from a day to another the day logged is always the day before dragging.

Why ?

And anyone know how I can pass my appointment from a cell to another ?

EDIT: I'm trying to use the answer below but have some issues:

I have added the cdkDropListGroup attribute to the tbody of my table (which show all the days)

And here is one cell of the table:

<div #dayCell class="day-cell" cdkDropList [cdkDropListData]="schedulesOfDay.schedulesWrapper" (cdkDropListDropped)="drop($event)">
  <div>{{day.getDate()}}</div>
  <div class="schedule-wrapper full-width">

    <ng-container *ngFor="let scheduleWrapper of schedulesOfDay.schedulesWrapper">
      <ng-container *ngIf="scheduleWrapper.isShowed">
        <div >
          <div class="schedule" cdkDrag
               [style.width.px]="getScheduleWidth(scheduleWrapper)"
               [style.height.px]="20"
               [style.top.px]="getScheduleHeightOffset(scheduleWrapper)"
               [style.background]="scheduleWrapper.schedule.background">
          >
            <div class="schedule-details">
              <div class="schedule-text">{{getScheduleTitle(scheduleWrapper)}}</div>
            </div>
          </div>
        </div>
      </ng-container>
    </ng-container>

  </div>
</div>

I have the cdkDropList on the entire cell, and a cdkDrag for each of my schedules. The problem is when I drag from a cell to another in the drop function the previousContainer and container are the same, so nothing is moved. (And I also print in console the day of the cell where the element is dropped and it always show the day where the schedule was before dragging).

I think the problem is the following:

When I move an element I need to change the date of this element (because I make a new render of my elements just after). But I can't get the specific moved element from the container, I can just have all the elements

1

1 Answers

1
votes

One possible way to create multiple drag and drop zones is to use cdkDropListGroup attribute on the parent element.

<div class="container" cdkDropListGroup>
    <app-calendar *ngFor="let date of dates" [date]="date"></app-calendar>
</div>

Once you have this setup. Your app-calendar component can have the following markup:

<div class="tasks" cdkDropList [cdkDropListData]="dayObj.schedules"
     (cdkDropListDropped)="drop($event)">
    <div *ngFor="let schedule of dayObj.schedules" cdkDrag>
        {{ schedule.title }}
    </div>
</div>

And then handling the drop:

  drop(event: CdkDragDrop<any>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }
  }

These two methods moveItemInArray and transferArrayItem are from here:

import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';

Working stackblitz.