无法将外部事件拖放到全日历日期GridView中 [英] Unable to drag and drop external events into FullCalendar dayGridView

查看:22
本文介绍了无法将外部事件拖放到全日历日期GridView中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用PrimeNG FullCalendar组件时遇到的一个非常奇怪的问题让我抓狂,这个组件:https://primefaces.org/primeng/showcase/#/fullcalendar

基于角度全日历组件,此组件:https://fullcalendar.io/

具体地说,我正在尝试实现类似于最后一个链接的行为,在该链接中,可拖动的事件被移动到日历中。

与链接示例不同,我的可拖动事件具有开始结束时间。 例如,我希望将事件拖到日历的特定日期中,指定事件开始于07:00,结束于15:00(这是因为我的日历代表的是工作班次日历,其中将人员安排在特定的时间范围内工作)。

您可以在这里找到我的完整代码:https://bitbucket.org/dgs_poste_team/soc_calendar/src/master/

您可以在app-component视图中看到的OK:

<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>组件,显示我可以拖入特定工作班次日历中的事件人员列表。

在右侧我有呈现日历的<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 }
};

我将角色事件的标题放在哪里(它工作得很好)。然后我放入(现在是静电,那我就动态化)startTime,即事件的开始时间(例如:我将Person Event拖到某一天,表示此事件必须在拖拽事件的当天18:00开始),duration表示事件在开始时间8小时后结束。

好的,在这种情况下,它似乎工作得"很好",实际上,当我将角色事件拖到特定日期时,它会出现在日历中,下面是一个屏幕截图:

例如,在前面的屏幕截图中,我将Persona 2事件拖入日期为2017年2月22日的那一天,它就在这里(其他事件来自我的代码中定义的静电事件数组)

注意的第一件奇怪的事:我预计事件以指示开始时间的内容开始(至于为2月9日设置的事件,以4p开始,表示此事件在此特定日期的16:00开始)。

好的,那么非常奇怪的是:如果我将return dEvent对象的startTime属性更改为小于16:00的值,它将不再起作用!

例如,使用:

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

这意味着:活动在日历中所选日期的下午4点开始,在同一天的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"不起作用。

出了什么问题?我遗漏了什么?如何更改代码以解决此问题?

推荐答案

将事件拖入dayGridMonth视图时,FullCalendar不考虑原始事件定义中设置的allDay值,始终设置allDay: true。这意味着,默认情况下,拖放到dayGridMonth视图中的事件被视为/假定为全天事件。

但是,当您使用startTimeduration设置创建计时事件时,该事件不再是全天事件。当您将此类事件拖到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);
}
但请注意,这将影响所有拖动的事件。因此,您可能希望根据可以由初始事件创建期间定义的某些标志确定的条件将All-day设置为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

我希望这会有帮助,祝你好运。

这篇关于无法将外部事件拖放到全日历日期GridView中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆