Using the latest version of fullCalendar (5.3.2) I want to hide some events that correspond to resources I don't want to show now in a given view. The standard way to do this is using an eventClassNames
function to check for it and add a "hidden" class. Something like this:
eventClassNames: function(arg) {
my_class = "";
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
my_class = 'hidden';
}
}
return my_class;
}
using a simple CSS:
.fc-event.hidden {
display: none;
}
This works fine, but has a problem when there is an overlap between a hidden event and a showed one. For instance in this case:
events: [
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
Only event with real_rc == 1
should be displayed, and in fact it is right, but the space used by the hidden event is reserved as you can see in this image:
If the event with the real_rc: 2
is ommited in the event
list the result is the expected:
I've used the Chrome DevTools to try to figure out what's happening and I think the problem is that the 'hidden' class is not set on the "outermost event element" as the fullCalendar states, but to a inner one:
(first DIV is the first event and as you can see the hidden
class is set but not to the DIV, but to the a
tag)
IMHO this is a fullCalendar bug, but now I have a problem and I need a solution. My options are:
$(".fc-event.hidden").parent().remove()
when the events are loaded and showed but since v3 nothing like this exists UPDATE and even if it exist, with the current v5 removing the DOM element doesn't resize the other event boxes.real_rc != 1
Is there a way to circumvent this problem without creating a new one? (I feel that the easiest option is to find a hook that allows me do the option number 2, but I have spent all the day and I haven't found anything).
As you already noticed, CSS and JS cannot help here because the events are placed using position:absolute
so removing one event (even completely from the DOM) won't affect the display of the other ones. The only way is to remove the event form the calender before rendring.
So remove the event instead of adding a class:
eventClassNames: function(arg) { /* you can also use "eventDidMount" */
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
arg.event.remove(); /* HERE */
}
}
},
Full code:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
initialDate: '2020-12-22',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
height: 'auto',
eventClassNames: function(arg) {
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
arg.event.remove();
}
}
},
events: [
{
title: 'Test Resource 1',
real_rc: '1',
start: '2020-12-22 13:00',
end: '2020-12-22 14:00'
},
{
title: 'Also resource 1',
real_rc: '1',
start: '2020-12-22 13:30',
end: '2020-12-22 14:30'
},
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
});
calendar.render();
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
<link rel="stylesheet" href="https://unpkg.com/fullcalendar@5.1.0/main.min.css">
<script src="https://unpkg.com/fullcalendar@5.1.0/main.min.js"></script>
<div id='calendar'></div>
Another idea is to control the display
of the event like below:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
initialDate: '2020-12-22',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
height: 'auto',
eventDidMount: function(arg) {
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
arg.event.setProp( 'display', 'none' );
}
}
},
events: [
{
title: 'Test Resource 1',
real_rc: '1',
start: '2020-12-22 13:00',
end: '2020-12-22 14:00'
},
{
title: 'Also resource 1',
real_rc: '1',
start: '2020-12-22 13:30',
end: '2020-12-22 14:30'
},
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
});
calendar.render();
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
<link rel="stylesheet" href="https://unpkg.com/fullcalendar@5.1.0/main.min.css">
<script src="https://unpkg.com/fullcalendar@5.1.0/main.min.js"></script>
<div id='calendar'></div>
An interactive demo where you can toggle display:
var rc = "1";
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
initialDate: '2020-12-22',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
height: 'auto',
eventDidMount: function(arg) {
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != rc) {
arg.event.setProp( 'display', 'none' );
}
}
},
viewDidMount: function(arg) {
var es = calendar.getEvents();
for(var i=0;i<es.length;i++)
es[i].setProp( 'display', 'auto' )
},
events: [
{
title: 'Test Resource 1',
real_rc: '1',
start: '2020-12-22 13:00',
end: '2020-12-22 14:00'
},
{
title: 'Also resource 1',
real_rc: '1',
start: '2020-12-22 13:30',
end: '2020-12-22 14:30'
},
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
});
calendar.render();
document.querySelector("#toggle").addEventListener('click',function() {
if (rc=="1") rc="2"; else rc = "1";
/* trigger view change */
calendar.changeView('dayGridMonth');
calendar.changeView('timeGridWeek');
});
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
<link rel="stylesheet" href="https://unpkg.com/fullcalendar@5.1.0/main.min.css">
<script src="https://unpkg.com/fullcalendar@5.1.0/main.min.js"></script>
<button id="toggle">toggle</button>
<div id='calendar'></div>