This code is for a conference room rental service. I have so many problems with time zones and such using FullCalendar that I’m on the brink of just rewriting an entire calendar system from scratch.
I’m using adminlte and free version of fullCalendar v5.10.1 that came with adminlte. My problem is I need to add non clickable (editable:false) events that attach to my events from database. I’m very close achieving that using groupId.
jsFiddle
This is my code simplified (it might fail so added a fiddle similar to this)
var globalevents;
var containerEl = document.getElementById('external-events');
var calendarEl = document.getElementById('calendar');
const calendar = new Calendar(calendarEl, {
locale: "<%= language %>",
timeZone:"UTC",
headerToolbar: {
left : 'prev,next today',
center: 'title',
right : 'dayGridMonth,timeGridWeek,listMonth'
},
views:{
timeGridWeek:{
dayHeaderFormat:{
day: 'numeric',
weekday: 'long',
},
}
},
height: '100%',
allDaySlot: false,
themeSystem: 'bootstrap',
events: async function( fetchInfo, successCallback, failureCallback ) {
let _start = new Date(new Date(parseInt(fetchInfo.start.valueOf())));
let _end = new Date(new Date(parseInt(fetchInfo.end.valueOf())));
let d = _start.getDate(),
m = _start.getMonth()+1,
y = _start.getFullYear();
let _d = _end.getDate(),
_m = _end.getMonth()+1,
_y = _end.getFullYear();
globalevents= await getEvents("1",y+"-"+m+"-"+d,_y+"-"+_m+"-"+_d);
addGroup(globalevents);
successCallback(globalevents);
},
initialView:"timeGridWeek",
snapDuration:'00:10:00',
slotDuration:'00:30:00',
slotMinTime:'06:00:00',
slotMaxTime:'24:00:00',
eventResizableFromStart:true,
editable : true,
droppable : true, // this allows things to be dropped onto the calendar !!!
});
function addGroup (infos) {
infos.forEach(element => {
let _top = new Date(element.start).getTime();
_top-=element.prepTime*1000*60;
let _bot = new Date(element.end).getTime();
_bot+=element.cleanTime*1000*60;
console.log(element)
calendar.addEvent({
title : 'Prepare',
start : new Date(_top),
end : new Date(element.start),
backgroundColor: "#b8622d",
borderColor: "#b8622d",
groupId:element.groupId,//"219_order"
eventType:"prep",
display:'block'
// editable: false,
});
calendar.addEvent({
title : 'Cleanup',
start : new Date(element.end),
end : new Date(_bot),
backgroundColor: "#b8622d",
borderColor: "#b8622d",
groupId:element.groupId,//"219_order"
eventType:"prep",
display:'block'
// editable: false,
});
});
}
calendar.render();
//JSON from backend
{
title: "Admin",
start: "2023-12-29T08:30:00.000Z",
end: "2023-12-29T15:30:00.000Z",
backgroundColor: "#00a65a",
borderColor: "#00a65a",
allDay: false,
groupId: id+"_order", //like "219_order"
cleanTime: 30,
prepTime: 30,
}
Using this, top and bottom events are sticking to main event but at the same time they are resizable and if “prep” event is resized, it’s main event change size too. And if main event resizes, these maintenance events resize too.
If I make these extra events non editable then they stay in place and stop sticking to main event. I tried deleting all extra events every drag-drop-resize-mounted, recreated them using calendar.getEvents().foreach(…) but it gets very slow, cant have that in production.
Old approach:
// calendar.getEvents().forEach(element => {
// if(element.extendedProps.eventType == "prep")
// element.remove();
// else {
// addClean(element); //smaller version of addGroup function
// addPrep(element); //smaller version of addGroup function
// }
// });
I put this code in eventDrop, eventResize,viewDidMount and before calendar.render(), but it was slow and did not render in first render. Had to switch views or move one of the events to render extra events.
Tried display:”background” for extra events but then other event gets overlapped on them.
My needs are :
- top and bottom events should block other events overlapping on them
- top and bottom events are fixed size in duration, if main event change duration these will stick to start and end.
- (this may be an other question but:) preperation events should be hidden in month view
If there is a limitation about this (i tried everything in my power) I can work with enlarged events initial time with preperation times, then putting divs inside events and coloring start and end differently. Like event.start += prepTime. Then using eventContent I can add custom styling to events. But it seems too low level intervention that might cause more problems.