Невозможно перетащить внешние события в FullCalendar dayGridView - PullRequest
2 голосов
/ 28 мая 2020

Я схожу с ума от очень странной проблемы, с которой сталкиваюсь, используя компонент PrimeNG FullCalendar , этот: https://primefaces.org/primeng/showcase/# / fullcalendar

Это основано в компоненте Angular FullCalendar , этот: https://fullcalendar.io/

В частности, я пытаюсь реализовать поведение, подобное последней ссылке, где перемещается перетаскиваемое событие в календарь.

В отличие от примера ссылки мои перетаскиваемые события имеют время начало и время конец . Например, я хочу перетащить вечер в определенный c день моего календаря, указав, что он начинается с 07: 00 и заканчивается в 15: 00 (это потому, что мой календарь представляет календарь рабочей смены, куда помещают человека, работающего в конкретном c временном диапазоне).

Здесь вы можете найти весь мой код: https://bitbucket.org/dgs_poste_team/soc_calendar/src/master/

Хорошо, как вы можно увидеть в представлении app-component , которое у меня есть:

<div class="container">
  <div class="row">
    <div class="col-12">
      <app-header></app-header>
    </div>

    <div class="row">
      <div class="col-4">
        <p>DRAGGABLE</p>
        <app-people-list></app-people-list>
      </div>
      <div class="col-8">
        <app-fullcalendar></app-fullcalendar>
      </div>
    </div>
  </div>
</div>

Слева находится компонент <app-people-list>, показывающий список событий \ людей, которых я могу перетащить в свой календарь для определенной c рабочей смены.

Справа у меня есть компонент <app-fullcalendar>, отображающий мой календарь.

В класс PeopleListComponent (контроллер app-people-list компонент) У меня есть этот метод ngAfterViewInit:

ngAfterViewInit() {
  console.log("PEOPLE LIST ngAfterViewInit() START !!!")
  var self = this

  new Draggable(this.draggablePeopleExternalElement.nativeElement, {
    itemSelector: '.fc-event',
    eventData: function(eventEl) {
      console.log("DRAG !!!");
      console.log("SELECTED SHIFT: " + self.selectedShift.value);

      //var returnedEvent = self.createEventObject(self.selectedShift.value, eventEl.innerText);

      //return returnedEvent;

      var returnedEvent = {
        title: eventEl.innerText,
        startTime: "18:00",
        duration: {
          hours: 8
        }
      };

      return returnedEvent;
    }
  });

}

Как видите, он создает объект Draggable, используемый для перетаскивания события \ человека из моего списка в календарь. На данный момент он возвращает такой объект:

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "18:00",
  duration: { hours: 8 }
};

, где я помещаю заголовок человека \ события (он отлично работает). Затем я помещаю (на данный момент это stati c, затем я сделаю его динамическим c) startTime, которое является временем начала события (например: я перетаскиваю человека \ событие в указанный c день, это означает, что это событие должно начинаться в 18:00 того дня, в который событие было перетащено), а duration означает, что событие закончится через 8 часов после времени начала.

Хорошо , в этом случае, похоже, он работает "нормально", на самом деле, когда я перетаскиваю человека \ событие в определенный c день, когда он появляется в календаре, вот скриншот:

enter image description here

Например, на предыдущем снимке экрана я перетащил событие PERSONA 2 в день с датой 22 февраля 2017 , и оно здесь (другие события исходил из массива событий stati c, определенных в моем коде)

Первая странная вещь, которую я заметил: я ожидал, что таким образом событие начинается с того, что указывает время начала (что касается событий, установленных на 9 февраля, которые начинается с 4p indic при том, что это событие начинается в 16:00 этого дня c).

Хорошо, тогда очень странная вещь: если я изменю свойство startTime моего ReturnEvent объект со значением меньше 16: 00 он больше не работает !!!

Например, используя:

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "16:00",
  duration: {hours: 8}
};

это означает: событие начинается в 16:00 выбранного дня в календаре и заканчивается в 00:00 того же дня. Когда я перетаскиваю это событие в календарь, оно не появляется в календаре. Не рендерится !!! Это происходит для всех startTime предыдущих 17:00, и я не могу понять почему. В консоли JavaScript я не получаю сообщения об ошибке.

Для полноты, в класс FullcalendarComponent (класс, который контролирует полный компонент календаря) у меня есть:

@Component({
  selector: 'app-fullcalendar',
  templateUrl: './fullcalendar.component.html',
  styleUrls: ['./fullcalendar.component.css']
})
export class FullcalendarComponent implements OnInit {

  events: any[];
  options: any;
  header: any;

  //people: any[];

  @ViewChild('fullcalendar') fullcalendar: FullCalendar;


  constructor(private eventService: EventService) {}

  ngOnInit() {
    this.eventService.getEvents().then(events => {
      this.events = events;
    });

    this.options = {
      plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin, listPlugin],
      defaultDate: '2017-02-01',
      header: {
        left: 'prev,next',
        center: 'title',
        right: 'dayGridMonth,timeGridWeek,timeGridDay'
      },
      editable: true,

      dateClick: (dateClickEvent) => { // <-- add the callback here as one of the properties of `options`
        console.log("DATE CLICKED !!!");
      },

      eventClick: (eventClickEvent) => {
        console.log("EVENT CLICKED !!!");
      },

      eventDragStop: (eventDragStopEvent) => {
        console.log("EVENT DRAG STOP !!!");
      },

      eventReceive: (eventReceiveEvent) => {
        //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected shift: " + eventReceiveEvent.selectedShift);
        //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected start: " + eventReceiveEvent.event.start);

        console.log(eventReceiveEvent);
        this.eventService.addEvent(eventReceiveEvent);
      }
    };

  }

}

Как вы можете видеть, он содержит этот метод:

eventReceive: (eventReceiveEvent) => {
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected shift: " + eventReceiveEvent.selectedShift);
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected start: " + eventReceiveEvent.event.start);

  console.log(eventReceiveEvent);
  this.eventService.addEvent(eventReceiveEvent);
}

, которые получают предыдущее событие, сгенерированное компонентом списка людей, и помещают это событие в массив (вызывая службу), он отлично работает.

Я действительно не понимаю, что может быть не так в моем коде и почему при использовании значения startTime <"17:00" он не работает. </p>

Что не так? Что мне не хватает? Как я могу изменить свой код, чтобы решить эту проблему?

1 Ответ

2 голосов
/ 29 мая 2020

При перетаскивании события в представление dayGridMonth FullCalendar не учитывает значение allDay, установленное в исходном определении события, и всегда устанавливает allDay: true. Это означает, что по умолчанию события, перетаскиваемые в представление dayGridMonth, считаются / предполагаются как события на весь день.

Однако, когда вы создаете событие с заданным временем с установленными startTime и duration, это мероприятие больше не является мероприятием на весь день. И когда вы перетаскиваете такое событие в представление dayGridMonth, FullCalendar не позволяет перетащить это событие в представление.

То, что вы описываете как самая странная вещь , - это то, что когда вы создаете следующее событие;

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "16:00",
  duration: {hours: 8}
};

время окончания этого события после сегодняшнего дня, и FullCalendar считает это событием на весь день. И поскольку это событие на весь день, его можно поместить в ячейку на весь день .

Однако, когда вы создаете следующее событие:

var returnedEvent = {
  title: eventEl.innerText,
  startTime: "15:00",
  duration: {hours: 8}
};

время окончания этого события - сегодня, и FullCalendar считает это не событием на весь день, а событием по времени . И поскольку это не мероприятие на весь день, не разрешено помещать его в слот на весь день .

Вы можете наблюдайте за тем же поведением, переключившись на просмотры неделя или день и попытайтесь перетащить события в строку весь день вверху. Он не позволяет отбрасывать временные события в эту строку, в то время как позволяет отбрасывать временные события в любую другую строку.

В результате; вам нужен обходной путь для FullCalendar, чтобы разрешить синхронизированные события быть помещенными в слот целый день . Как уже было сказано, достаточно просто преобразовать дневные события в рассчитанные по времени после того, как события будут проанализированы FullCalendar. Это можно сделать в обратном вызове eventReceive.

eventReceive: receivedEvent => {
  receivedEvent.event.setAllDay(false, {maintainDuration: true})
}

Короче говоря, в вашем FullcalendarComponent;

eventReceive: (eventReceiveEvent) => {
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected shift: " + eventReceiveEvent.selectedShift);
  //console.log("EXTERNAL EVENT LAND ON THE CALENDAR. Title: " + eventReceiveEvent.event.title + " Selected start: " + eventReceiveEvent.event.start);

  //console.log(eventReceiveEvent);
  eventReceiveEvent.event.setAllDay(false, {maintainDuration: true})
  this.eventService.addEvent(eventReceiveEvent);
}

Но учтите, что это повлияет на все перетаскиваемые события. Таким образом, вы можете установить значение false для всего дня в зависимости от условия, которое может быть определено некоторым флагом, определенным во время первоначального создания события. Это во многом зависит от вашего варианта использования.

Связанные документы:
https://fullcalendar.io/docs/eventReceive
https://fullcalendar.io/docs/external-dragging
https://fullcalendar.io/docs/event-parsing
https://fullcalendar.io/docs/Event-setAllDay
https://fullcalendar.io/docs/allDayMaintainDuration

Надеюсь, это поможет, удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...