I'm using FullCalendar to display calendar events. I let the admin user reschedule an event by dragging an event to a different calendar day. If they try to reschedule an event to a day that cannot accept an event, the code uses info.revert() to "undo" the drag 'n drop.
All that works fine. However, when I show 2 calendars side-by-side (useful if they want to reschedule an event to a different month), I try to run the same code, but info.revert() throws this error:
Uncaught TypeError: info.revert is not a function
I see from the documentation here https://fullcalendar.io/docs/eventReceive that info.revert() should work here. Can anyone help me out?
FYI, here is my calendar defintion:
var calendar = new FullCalendar.Calendar(cal, {
plugins: [ 'bootstrap', 'interaction', 'dayGrid', 'dayGridPlugin', 'timeGrid', 'list' ],
themeSystem: 'bootstrap',
events: 'ajax/calendar.php?action=get_monthly_patrol_calendar',
showNonCurrentDates:false,
isRTL: KTUtil.isRTL(),
contentHeight: 'auto',
nowIndicator: show_now_indicator,
now: TODAY,
defaultDate: TODAY,
initialDate: TODAY,
defaultView: 'dayGridMonth',
eventOrder: 'order_by',
navLinks: true,
eventLimit: false, // true to allow "more" link when too many events
eventResizableFromStart: false, //Whether the user can resize an event from its starting edge.
eventDurationEditable: false, //Allow events’ durations to be editable through resizing.
eventResourceEditable: true, //Determines whether the user can drag events between resources.
droppable:true, //Determines if external draggable elements or events from other calendars can be dropped onto the calendar.
eventStartEditable: true, //Allow events’ start times to be editable through dragging.
editable: true, //Determines whether the events on the calendar can be modified.
eventDrop: function(info) { //fires when drag to another date in the same calendar month
if (info.event.extendedProps.has_events==true) {
reschedule_event(info);
}
else {
info.revert();
}
},
eventReceive: function(info) { //fires when drag to another date in the A DIFFERENT calendar month
if (info.event.extendedProps.has_events==true) {
reschedule_event_to_new_month(info);
}
else {
info.revert(); //////////////////////////this is the code that throws the error!!!!!!
}
},
eventClick: function(info) {
do_event_click(info);
},
eventRender: function(info) {
var element = $(info.el);
},
header: {
left: '',
center: 'title',
right: 'prev,next today',//'dayGridMonth,dayGridWeek,dayGridDay'
},
});
calendar.render();
Related
Good morning!
I have a list view set up in full calendar and have noticed that it will not display events beyond the end of the year. With it being now mid-December, this is a bit of a problem for me. We have several event that should be displaying in this list. When I change the view to month I have to click the next month button to get next years events, but at least with that I do sucessfully see the events in question.
Is there a way for my list view calendars to roll-over and include next year entries as I approach the end of the current year?
Here is an excerpt of what I have that effects the display of my calendar:
{url:'https://calendar.mydomain.com/services/id/38djsuw3hr-au8reh39dq/organization/1/department/13/',event_properties:{color:'#6a9b49'}},
]
function data_req (url, callback) {
req = new XMLHttpRequest()
req.addEventListener('load', callback)
req.open('GET', url)
req.send()
}
function add_recur_events() {
if (sources_to_load_cnt < 1) {
$('#calendar').fullCalendar('addEventSource', expand_recur_events)
} else {
setTimeout(add_recur_events, 30)
}
}
function load_ics(ics){
data_req(ics.url, function(){
$('#calendar').fullCalendar('addEventSource', fc_events(this.response, ics.event_properties))
sources_to_load_cnt -= 1
})
}
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: '',
center: '',
right: '' //view options on top-right (supported by v2.9.1 currently)
},
viewDisplay: function(view) {
parent.setIframeHeight(iframeId) ;
},
eventClick: function(event) {
// opens events in a new window or tab
window.open(event.url,);
return false;
},
// eventDataTransform: function(rawEventData){
// return {title: rawEventData.Title
// };
// },
defaultView: $(window).width() < 765 ? 'listYear':'listYear', //carryover code from full sized calendar
nowIndicator: false, //show a marker for current time
eventLimit: 4, // allow "more" link when too many events
fixedWeekCount: false, // have blank rows on a 6 or 7 row month
listDayFormat: 'MMMM Do',
listDayAltFormat: false,
allDayDefault: false,
noEventsMessage: "No Currently Scheduled Events"
})
sources_to_load_cnt = ics_sources.length
for (ics of ics_sources) {
load_ics(ics)
}
add_recur_events()
})
All I see is my "NoEventsMessage" text when in list view. If I create a test event the occurs prior to the end of the year it shows up in list view.
Any ideas on spanning calendar end?
thanks
[Edit: I should say that the link at the top is a JSON feed, so I am not using a prefilled list of events from within my script or from within an external file]
Here is how I solved it.
I created a custom view entry for the specific default view called "list" and gave it a one year duration:
views: {
list: {
duration: { days:365 }
}
},
I reset my default view from the dynamic version I carried over from my full-sized calendar (since I am using this in a column anyway and the window width call is not needed):
From:
defaultView: $(window).width() < 765 ? 'listYear':'listYear',
To:
defaultView: 'list',
After doing those things my January entries for next year began to display in list view.
Here is what my display calls look like (If someone wants to edit this to make it look prettier and more efficient, I don't mind :).
ics_sources = [
{url:'https://calendar.mydomain.com/services/id/38djsuw3hr-au8reh39dq/organization/1/department/13/',event_properties:{color:'#6a9b49'}},
]
function data_req (url, callback) {
req = new XMLHttpRequest()
req.addEventListener('load', callback)
req.open('GET', url)
req.send()
}
function add_recur_events() {
if (sources_to_load_cnt < 1) {
$('#calendar').fullCalendar('addEventSource', expand_recur_events)
} else {
setTimeout(add_recur_events, 30)
}
}
function load_ics(ics){
data_req(ics.url, function(){
$('#calendar').fullCalendar('addEventSource', fc_events(this.response, ics.event_properties))
sources_to_load_cnt -= 1
})
}
$(document).ready(function() {
$('#calendar').fullCalendar({
header: false,
viewDisplay: function(view) {
parent.setIframeHeight(iframeId) ;
},
eventClick: function(event) {
// opens events in a new window or tab
window.open(event.url,);
return false;
},
defaultView: 'list',
nowIndicator: false, //show a marker for current time
eventLimit: 4, // allow "more" link when too many events
fixedWeekCount: false, // have blank rows on a 6 or 7 row month
listDayFormat: 'MMMM Do',
listDayAltFormat: false,
noEventsMessage: "No Currently Scheduled Events",
views: {
list: {
duration: { days: 365 },
}
}
})
sources_to_load_cnt = ics_sources.length
for (ics of ics_sources) {
load_ics(ics)
}
add_recur_events()
})
Thanks.
[edit: removed extraneous backticks from answer.]
I am trying to create a view in fullcalendar to show when some people are off duty.
People might be off the from eg. 10:00AM to 09:00AM the next day and I would like to show the event in the allDay-slot in fullcalendar and also show the start and end of the event as part of the title.
If I set the allDay-property on the event, it will display the event in the allDay-slot but it displays the start and end as '00:00' instead of '10:00' and '09:00'.
The other option I have tried is setting a custom property on the event-object called isDayOff, and then in the eventRender-callback set the standard allDay-property on the rendered event. This seems to work, but the event is not rendered in the allDay-slot on load, but only rendered in the allDay-slot when clicking back or forth to the prev/next day and then back.
How do I create this view?
I have created a fiddle to exemplify: http://jsfiddle.net/2ptqe5na/31
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: '',
center: 'title'
},
defaultDate: '2018-07-23',
defaultView: 'agendaDay',
events: [
{
title: 'A',
start: '2018-07-23T10:00:00',
end: '2018-07-24T09:00:00',
allDay: true //standard property
},
{
title: 'B',
start: '2018-07-23T08:00:00',
end: '2018-07-23T08:30:00',
isDayOff: true //custom property
}
],
eventClick: function(calEvent, jsEvent, view) {
alert('Event: ' + calEvent.title);
},
eventRender: function(event, element, view)
{
if(event.isDayOff==true)
{
event.allDay = event.isDayOff;
}
event.title = event.title+"\n "+event.start.format('MMM DD HH:mm')+" - "+event.end.format('MMM DD HH:mm');
}
});
});
i'm using fullcalendar version 3 with external event. and my problem was that wanted to fix dropped point when drag/drop left side item to calendar.
for example, if external "My event 1" drag to "test1 room" (has start:13:00:00/end:17:00:00 time attribute) calendar.
"My event 1" will be on 13:00:00 start and 17:00:00 end time ONLY. never change to another time on "test1 room" row.
$(function() { // document ready
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events .fc-event').each(function() {
// store data so the calendar knows to render an event upon drop
$(this).data('event', {
title: $.trim($(this).text()), // use the element's text as the event title
stick: true // maintain when user navigates (see docs on the renderEvent method)
});
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
/* initialize the calendar
-----------------------------------------------------------------*/
$('#calendar').fullCalendar({
now: '2016-01-07',
editable: true, // enable draggable events
droppable: true, // this allows things to be dropped onto the calendar
aspectRatio: 1.8,
scrollTime: '00:00', // undo default 6am scrollTime
header: {
left: 'today prev,next',
center: 'title',
right: 'timelineDay,timelineThreeDays,agendaWeek,month'
},
defaultView: 'timelineDay',
views: {
timelineThreeDays: {
type: 'timeline',
duration: { days: 3 }
}
},
resourceLabelText: 'Rooms',
resources: [
{ id: 'a', title: 'test1 room', start:"2016-01-07T13:00:00",end: '2016-01-07T17:00:00' },
{ id: 'b', title: 'test2 room', eventColor: 'green' },
{ id: 'c', title: 'test3 room', eventColor: 'orange' },
],
events: [
{ id: '1', resourceId: 'b', start: '2016-01-07T02:00:00', end: '2016-01-07T07:00:00', title: 'event 1' }
],
drop: function(date, jsEvent, ui, resourceId) {
console.log('drop', date.format(), resourceId);
// is the "remove after drop" checkbox checked?
if ($('#drop-remove').is(':checked')) {
// if so, remove the element from the "Draggable Events" list
$(this).remove();
}
},
eventReceive: function(event) { // called when a proper external event is dropped
console.log('eventReceive', event);
},
eventDrop: function(event) { // called when an event (already on the calendar) is moved
console.log('eventDrop', event);
}
});
});
To stop events being dragged around after they're placed on the calendar, you can simply set the editable option:
editable: false
This stops internal dragging/dropping, but doesn't affect external dropping (which is controlled by the "droppable" option).
If you only want this rule to apply to specific events, you can set editable: true in general, but then set editable: false as a property of individual events - this will override the global setting. See https://fullcalendar.io/docs/event_data/Event_Object/ for details of which settings can be over-ridden at the event level.
i'm trying to change external duration on fullcalendar external-dragging example.
https://fullcalendar.io/js/fullcalendar-scheduler-1.2.0/demos/external-dragging.html
the example duration was 02:00:00. but I would like to be changed when drag on calendar.
for example baed on above link, pre-duration of rooms were 02:00:00 and 03:00:00 like "Auditorium A" was 02:00:00 and "Auditorium B" was 03:00:00.
and then, when I drag some external item to calendar. then change the item duration 02:00:00 on "Auditorium A" or 03:00:00 on "Auditorium B".
$(function() { // document ready
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events .fc-event').each(function() {
// store data so the calendar knows to render an event upon drop
$(this).data('event', {
title: $.trim($(this).text()), // use the element's text as the event title
stick: true // maintain when user navigates (see docs on the renderEvent method)
});
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
/* initialize the calendar
-----------------------------------------------------------------*/
$('#calendar').fullCalendar({
now: '2016-01-07',
editable: true, // enable draggable events
droppable: true, // this allows things to be dropped onto the calendar
aspectRatio: 1.8,
scrollTime: '00:00', // undo default 6am scrollTime
header: {
left: 'today prev,next',
center: 'title',
right: 'timelineDay,timelineThreeDays,agendaWeek,month'
},
defaultView: 'timelineDay',
views: {
timelineThreeDays: {
type: 'timeline',
duration: { days: 3 }
}
},
resourceLabelText: 'Rooms',
resources: [
{ id: 'a', title: 'Auditorium A' },
{ id: 'b', title: 'Auditorium B', eventColor: 'green', start:"09:00", end:"11:00" },
{ id: 'c', title: 'Auditorium C', eventColor: 'orange', start:"13:30",end:"16:00" }
],
events: [
],
drop: function(date, jsEvent, ui, resourceId) {
console.log('drop', date.format(), resourceId);
// is the "remove after drop" checkbox checked?
if ($('#drop-remove').is(':checked')) {
// if so, remove the element from the "Draggable Events" list
$(this).remove();
}
},
eventReceive: function(event) { // called when a proper external event is dropped
console.log('eventReceive', event);
},
eventDrop: function(event) { // called when an event (already on the calendar) is moved
console.log('eventDrop', event);
}
});
});
one of above code, there are start/end attribute in resources. so I would like to be applied start/end time when left side external drag on calendar each of rooms.
I am using the fullcalendar jquery plugin to create a schedule of events. I want to prevent the user from dropping an external event on the calendar if it is earlier than current date.
This is my current code:
$('#edit_calendar').fullCalendar({
header:
{
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
titleFormat: { month: 'MMMM' },
defaultView: 'month',
droppable: true,
drop: function (date, jsEvent, ui, resourceId) {
//compare today's date with drop date - if in the past, don't allow
var today = moment().startOf('day');
var dropDate = moment(date).startOf('day');
if (dropDate < today)
{
//The alert is shown
alert("An event in the past cannot be added, updated, or deleted.");
return false;
}
else
{
var memberName = $(this).data('event').title;
var memberID = $(this).attr('id').toString();
//Create Event - add to array
var newEvent = new Object();
newEvent = {
title: memberName,
id: memberID,
start: date.format(),
end: date.format(),
objectID: 0
};
eventsAdded.push(newEvent);
}
},
...rest of code
If the event is dropped before the current day display the alert and do not create the event. If shown after the current day, create the event.
In the code above, the alert is shown, but the event is still created. If the event is dropped after the current day, the event is created.
I thought by adding return false after the alert is displayed it will prevent the event from being created. However, the alert is shown AND the event is created.
Do I have to remove the event or is there a way to prevent the event from being created?
I was able to restrict events when they are added or changed using the selectConstraint and eventConstraint respectively. However, I would like to add an alert when the user tries to update or add an event outside the start and end dates so they know why it is not working.
This is what I have:
$('#edit_calendar').fullCalendar({
header:
{
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
titleFormat: { month: 'MMMM' },
defaultView: 'month',
droppable: true,
drop: function (date, jsEvent, ui, resourceId) {
var memberName = $(this).data('event').title;
var memberID = $(this).attr('id').toString();
//Create Event - add to array
var newEvent = new Object();
newEvent = {
title: memberName,
id: memberID,
start: date.format(),
end: date.format(),
objectID: 0
};
eventsAdded.push(newEvent);
},
editable: true,
//The following constraints prevents the user from adding/updating/deleting events that are before the current date
//The end date is required. So, you can't add events over a year away from the current date
eventConstraint: {
start: moment().startOf('day'),
end: moment(moment().startOf('day'), 'MM-DD-YYY').add('days', 365)
},
selectConstraint: {
start: moment().startOf('day'),
end: moment(moment().startOf('day'), 'MM-DD-YYY').add('days', 365)
},
...rest of code...
Is there any way I can add an alert when the user tries to add or update an event ou
From the documentation:
eventDrop does not get called when an external event lands on the calendar. eventReceive is called instead
Having said that, in order to prevent the drop you need to go more back in the chain. You need to use "dropAccept". You can read about it in the documentation.
You can use 'removeEvents' to remove added event.
https://fullcalendar.io/docs1/event_data/removeEvents/
drop: function(date, jsEvent, ui, resourceId) {
var add = true;
... // Here decide whether to add or not
if(add){
;
}
else{
//use 'removeEvents' to remove added event
}
}