5

I am using Fullcalendar / Scheduler to show some events on a calendar. I get all my information from a REST service.

I know that Fullcalendar has a method that checks if an event is overlapping with another ( it does this when using the slotEventOverlap attribute ) so that it will make it 50% or less depending on how many events there are.

My question is this, has anyone any idea what that method is .. What I need to achieve is that when two overlapping events are on the calendar, they should be in red. Something like this:

enter image description here

I was thinking that somewhere in the library, when the computing is done, and the % are set, a new class can be added to these events, something like fc-overlap, that I could customize.

Or does anyone have any idea on how I could achieve this?

The only solution I can find is after I get the list of events, parse them in a function check if startTime & endTime overlap and somehow assign a class to only those that overlapp. (I can identify the events via their ID ) but this seems somehow defeating the purpose since the calendar is already doing a validation when it's rendering the events.

Vlad N
  • 631
  • 2
  • 10
  • 21
  • I was wondering if possible through CSS and I found that vertical events may be the ones that overlap. I'm not certain, but does it work if you apply the style to the `fc-v-event` class? If there's a case where events that overlap do not get this class or events that do overlap don't get this class then it would not work. – ThisClark Jun 21 '18 at 13:37
  • Unfortunately that doesn't work, I already looked at what classes each event has and they are no different from normal events that do not overlap. Only difference between them is that the overlapping events have their respective segments calculated then rendered. Fullcalendar does not add anything else to them – Vlad N Jun 21 '18 at 13:46
  • If that’s that’s the only difference, couldn’t you parse the style for the calculated properties then as a rule you would know they overlap and style accordingly? I think you’re looking to modify at the source function and I agree this would be more elegant. I’m just throwing out quick solution ideas here. – ThisClark Jun 21 '18 at 13:50
  • Unfortunately I can't do that since I don't know if there are 2 or 3 elements in conflict... that means the calculated result differs every time. – Vlad N Jun 22 '18 at 11:11
  • At what stage do you want to do this? On events load from remote or on event rendering? – Yuri Jun 25 '18 at 12:04

2 Answers2

3

There are two ways to do this:

  1. Server side: the best method in my opinion, definitely faster.

Assuming you have a DB table named events filled with your events, you can easily check if the current event overlaps some other in the current view. Example:

$output = [];
$my_start_date = $_GET['start'];
$my_end_date = $_GET['end'];
$result = $db->query("SELECT * FROM events WHERE 1;");
foreach ($result AS $row){
    $is_overlapping_class = "";
    if( isOverlapping($row['start'], $row['end']) )
        $is_overlapping_class = "my-custom-overlapping-class";

    $output[] = [
        "title" => $row['title'],
        "content" => $row['content'],
        "start" => date("Y-m-d", strtotime( $row['start'] )),
        "end" => date("Y-m-d", strtotime( $row['end'] )),
        "allDay" => boolval($row['allDay']),
        "className" => $is_overlapping_class
    ];
}

And the isOverlapping() function, very basic:

function isOverlapping( $start, $end ){
    GLOBAL $db;
    $result = $db->query("SELECT 1 FROM events WHERE date(date_start) >= date('$my_start_date') AND date(date_end) <= date('$my_end_date')");
    return $result->rowCount() > 1; // > 1 because one result will be surely the currently tested event
}
  1. Client side: I don't suggest this method when you have to display many events at the same time.

Define a function (found here) to check if the current event is overlapping any other event.

function isOverlapping( event ) {
    var array = $('#calendar').fullCalendar('clientEvents');
    for(i in array){
        if(array[i].id != event.id){
            if(!(Date(array[i].start) >= Date(event.end) || Date(array[i].end) <= Date(event.start))){
                return true;
            }
        }
    }
    return false;
}

Then, on event eventRender check for overlapping and add class:

$('#calendar').fullCalendar({
    events: [ ... ],
    eventRender: function(event, element) {
        if( isOverlapping( event ) ){
            element.addClass('my-custom-overlapping-class');
        }
    }
});

NOTE: this code is not tested as no source code was provided by the OP. Should give an idea of what needs to/can be done though.

Yuri
  • 3,082
  • 3
  • 28
  • 47
1

Answering by considering you are using full-calendar library from https://fullcalendar.io

Check the link https://fullcalendar.io/docs/slotEventOverlap which states that, whether you want to have overlapping events or not. Using keyword "slotEventOverlap" from above link, I have found out event associated to it in JS file https://fullcalendar.io/releases/fullcalendar/3.9.0/fullcalendar.js

where a function "generateFgSegHorizontalCss" uses keyword "slotEventOverlap" to get CSS related to event being shown.

Hope that using above information, you can try to figure next probable solution to create custom css for achieving your target.

Prasad Wargad
  • 737
  • 2
  • 7
  • 11