javascriptfullcalendar

How to hide content on days beyond the first day on a multi-day event in FullCalendar?


In FullCalendar there are events that can continue over the night, so you will have events that are in a new day, but FullCalendar makes it so that the content of the event in the first day is repeated in every other day that the event is on. What I'd like to achieve is that the content of the event starts on the first day and is hid.

I have used eventContent with success for a static FullCalendar, I made a class out of every event ID and assigned it to the event using eventClassNames and then I used eventContent to fetch all classes using the event ID and if the length of that array was 0, then I returned the event content. If the class count was not 0 but the event content was not found within the classes then it would also return the event content.

However the problem arises when you try to edit the event using editable, the above code works for static FullCalendar because when the first part of the event is loaded nothing with the class name will yet have been loaded so d1.length will be 0, when you start using editable all parts of the events will already have been loaded and the parts of a event when called can be 1, 2, 3 or more of the exact same event (not parts of the event, just a complete version of the event's el), to solve this I tried to check whether the event content was already on the screen by looping through all relevant classes however that results in the event seeing itself as shown and ends up showing nothing, or showing the event content on the wrong part of the event.

before moving an event

after moving an event

I've also tried splitting events which worked but, it also meant that when I tried to move the events using editable the events would be 2 separate events, maybe there is a way to make them act as one, I tried looking into this but nothing of relevance showed up...

The intended behavior is that only the first part of an event will have content (e.g title, time) and the second part on the next day is empty. However the behavior of the snippet below is that when you move an event, the content of other events clears & reappears when you move it again.

document.addEventListener('DOMContentLoaded', function() {
  var calendarEl = document.getElementById('calendar');
  var calendar = new FullCalendar.Calendar(calendarEl, {
    initialView: 'timeGridWeek',
    events: [{
        'id': 1,
        'title': 'event1',
        'start': '2024-11-05 20:00:00',
        'end': '2024-11-06 12:00:00'
      },
      {
        'id': 2,
        'title': 'event2',
        'start': '2024-11-07 14:00:00',
        'end': '2024-11-07 18:00:00'
      }
    ],
    editable: true,
    eventClassNames: function(arg) {
      return ['event-' + arg.event.id];
    },
    eventContent: function(arg) {
      var d1 = document.getElementsByClassName('event-' + arg.event.id);
      console.log(d1);
      for (var i = 0; i < d1.length; i++) {
        if (d1[i].innerText.includes(arg.event.title)) {
          return false;
        }
      }
      if (d1.length == 0) {
        return {
          html: arg.event.title
        };
      }
    }
  });
  calendar.render();
});
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.js'></script>

<div id='calendar'></div>


Solution

  • What I'd like to achieve is that the content of the event starts on the first day and is hid.

    If all you want to do is hide the event content on all but the first day - why don't you do that using CSS only?

    The a.fc-event elements the event content is shown in, also get the class fc-event-start in the first day column - so hide the details in all other such elements, that do not have that class?

    I removed your conditional logic for setting the event content here, and simply added

    .fc-event:not(.fc-event-start) .fc-event-main {
       display: none;
    }
    

    - that does achieve what you want, if I understood you correctly?

    document.addEventListener('DOMContentLoaded', function() {
      var calendarEl = document.getElementById('calendar');
      var calendar = new FullCalendar.Calendar(calendarEl, {
        initialView: 'timeGridWeek',
        events: [{
            'id': 1,
            'title': 'event1',
            'start': '2024-11-05 20:00:00',
            'end': '2024-11-06 12:00:00'
          },
          {
            'id': 2,
            'title': 'event2',
            'start': '2024-11-07 14:00:00',
            'end': '2024-11-07 18:00:00'
          }
        ],
        editable: true,
        eventClassNames: function(arg) {
          return ['event-' + arg.event.id];
        },
        eventContent: function(arg) {
          
            return {
              html: arg.event.title
            };
          
        }
      });
      calendar.render();
    });
    .fc-event:not(.fc-event-start) .fc-event-main {
       display: none;
    }
    <script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.js'></script>
    
    <div id='calendar'></div>