无法将外部事件拖放到 FullCalendar dayGridView 中
Unable to drag and drop external events into FullCalendar dayGridView
我正在为一个非常奇怪的问题发疯,我正在使用 PrimeNG FullCalendar 组件,这个:https://primefaces.org/primeng/showcase/#/fullcalendar
那是基于Angular FullCalendar组件,这个:https://fullcalendar.io/
特别是我正在尝试实现类似于最后一个 link 的行为,其中可拖动事件被移动到日历中。
与 link 示例不同,我的可拖动事件有一个 start 和一个 end 时间。
例如,我想将一个事件拖到日历的特定日期,指定它从 07:00 开始并在 15:00 结束(这是因为我的日历代表工作班次日历,其中将人员放在特定时间范围内工作)。
在这里你可以找到我的全部代码: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>
组件显示了 event\people 的列表,我可以将其拖到我的日历中以进行特定的工作班次。
在右侧,我有 <app-fullcalendar>
组件呈现我的日历。
进入PeopleListComponent
class(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
object,用于将我列表中的 event\person 拖到日历中。目前它正在返回一个 object 这样的:
var returnedEvent = {
title: eventEl.innerText,
startTime: "18:00",
duration: { hours: 8 }
};
我把 person\event 的标题放在哪里(效果很好)。然后我把(目前它是静态的,然后我会把它变成动态的)startTime
是事件的开始时间(例如:我将 person\event 拖到特定的一天,这意味着此事件必须在事件被拖动当天的 18:00 开始)和 duration
表示事件在开始时间后 8 小时结束。
好的,在这种情况下它似乎有效 "fine",实际上当我将 person\event 拖到特定日期时它会出现在日历中,这里是截图:
例如,在之前的屏幕截图中,我将 PERSONA 2 事件拖到日期为 22 Februrary 2017 的日期,它在这里(其他事件来自我的代码中定义的静态事件数组)
注意到的第一件奇怪的事情:我预计事件以指示开始时间的东西开始(至于为 2 月 9 日设置的以 4p 开始的事件表明这活动在这一天的 16:00 点开始。
好吧,然后是非常奇怪的事情:如果我更改我的 returnedEvent object 的 startTime 属性小于 16:00 的值不再起作用 !!!
例如,使用:
var returnedEvent = {
title: eventEl.innerText,
startTime: "16:00",
duration: {hours: 8}
};
这意味着:活动从日历中所选日期的下午 4 点开始,并在同一天的 00:00 结束。当我将此事件拖到日历中时,该事件不会出现在日历上。它没有渲染!它发生在所有 startTime
之前的 17:00,我不明白为什么。进入 JavaScript 控制台,我没有收到任何错误消息。
为了完整性,进入 FullcalendarComponent
class(控制完整日历组件的 class)我有:
@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
视图的事件是 considered/supposed 全天事件。
但是,当您创建一个设置了 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 认为此不是全天活动,而是定时活动。由于这 不是 全天活动,因此 不允许 将其放入 全天时段.
您可以通过切换到 week 或 day 视图并尝试将事件放入 all- 来观察相同的行为day 排在顶部。它不允许将定时事件放入该行,但允许将定时事件放入任何其他行。
因此;您需要一种解决 FullCalendar 的方法,以允许将定时事件放入 all-day 槽中。就像说的一样简单:)在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
希望对你有所帮助,祝你好运。
我正在为一个非常奇怪的问题发疯,我正在使用 PrimeNG FullCalendar 组件,这个:https://primefaces.org/primeng/showcase/#/fullcalendar
那是基于Angular FullCalendar组件,这个:https://fullcalendar.io/
特别是我正在尝试实现类似于最后一个 link 的行为,其中可拖动事件被移动到日历中。
与 link 示例不同,我的可拖动事件有一个 start 和一个 end 时间。 例如,我想将一个事件拖到日历的特定日期,指定它从 07:00 开始并在 15:00 结束(这是因为我的日历代表工作班次日历,其中将人员放在特定时间范围内工作)。
在这里你可以找到我的全部代码: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>
组件显示了 event\people 的列表,我可以将其拖到我的日历中以进行特定的工作班次。
在右侧,我有 <app-fullcalendar>
组件呈现我的日历。
进入PeopleListComponent
class(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
object,用于将我列表中的 event\person 拖到日历中。目前它正在返回一个 object 这样的:
var returnedEvent = {
title: eventEl.innerText,
startTime: "18:00",
duration: { hours: 8 }
};
我把 person\event 的标题放在哪里(效果很好)。然后我把(目前它是静态的,然后我会把它变成动态的)startTime
是事件的开始时间(例如:我将 person\event 拖到特定的一天,这意味着此事件必须在事件被拖动当天的 18:00 开始)和 duration
表示事件在开始时间后 8 小时结束。
好的,在这种情况下它似乎有效 "fine",实际上当我将 person\event 拖到特定日期时它会出现在日历中,这里是截图:
例如,在之前的屏幕截图中,我将 PERSONA 2 事件拖到日期为 22 Februrary 2017 的日期,它在这里(其他事件来自我的代码中定义的静态事件数组)
注意到的第一件奇怪的事情:我预计事件以指示开始时间的东西开始(至于为 2 月 9 日设置的以 4p 开始的事件表明这活动在这一天的 16:00 点开始。
好吧,然后是非常奇怪的事情:如果我更改我的 returnedEvent object 的 startTime 属性小于 16:00 的值不再起作用 !!!
例如,使用:
var returnedEvent = {
title: eventEl.innerText,
startTime: "16:00",
duration: {hours: 8}
};
这意味着:活动从日历中所选日期的下午 4 点开始,并在同一天的 00:00 结束。当我将此事件拖到日历中时,该事件不会出现在日历上。它没有渲染!它发生在所有 startTime
之前的 17:00,我不明白为什么。进入 JavaScript 控制台,我没有收到任何错误消息。
为了完整性,进入 FullcalendarComponent
class(控制完整日历组件的 class)我有:
@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
视图的事件是 considered/supposed 全天事件。
但是,当您创建一个设置了 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 认为此不是全天活动,而是定时活动。由于这 不是 全天活动,因此 不允许 将其放入 全天时段.
您可以通过切换到 week 或 day 视图并尝试将事件放入 all- 来观察相同的行为day 排在顶部。它不允许将定时事件放入该行,但允许将定时事件放入任何其他行。
因此;您需要一种解决 FullCalendar 的方法,以允许将定时事件放入 all-day 槽中。就像说的一样简单:)在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
希望对你有所帮助,祝你好运。