How to prevent event overlapping when updating existing events in Full Calendar?

Viewed 3051

I have used eventOverlap: false, and selectOverlap: false, to prevent the user from overlapping events. However, I am trying to prevent the user from overlapping existing events.

In my full calendar the user can click on an event, which opens a pop up dialog and allows the user to update the date/time of the selected event. However, the user is able choose a date/time where an event is already booked. Therefore, I want to have a validation on the Save button that checks if the updated date/time has an event or not before any changes are made. These two screen shots show this problem graphically. 1. Shows that event time is being updated. 2. Shows the event is overlapping after it has been updated

var events = []; //global array where all the events are stored

function FetchEventAndRenderCalendar() {
//fetch info from database and add it to the events array
events = [];
$.ajax({
    type: "GET",
    url: "/SessionScheduler/GetEvents",
    success: function (data) {
    $.each(data, function (i, v) {    
         events.push({
             id: v.Id,
             title: v.Title,
             description: v.Description,
             start: moment(v.StartDate),
             end: moment(v.EndDate),
             tutorName: v.TutorName,
             color: v.ThemeColour
            });
      })
     //then display the calendar with the events
      GenerateCalender(events);
   },
   error: function (error) {
       alert('failed');
     }
  })
}

This is the Save button where I want to have a validation check. I have looked at this solution but this didn't work for me

$('#btnSave').click(function () {
                    //validation
                    var selectedStartDate = moment(document.getElementById('txtStart').value.trim(), "DD/MM/YYYY HH:mm a").toDate();
                    var selectedEndDate = moment(document.getElementById('txtEnd').value.trim(), "DD/MM/YYYY HH:mm a").toDate();
                    if (selectedStartDate > selectedEndDate) {
                        alert('Invalid end date');
                        return;
                    }

                    if (selectedStartDate.getTime() == selectedEndDate.getTime()) {
                        alert('Start/End dates can not be the same');
                        return;
                    }

                    var data = {
                        Id: $('#hdEventID').val(),
                        Title: $('#txtTitle').val(),
                        StartDate: $('#txtStart').val(),
                        EndDate: $('#txtEnd').val(),
                        Description: $('#txtDescription').val(),
                        TutorName: $('#txtTutorName').val(),
                        ThemeColour: $('#ddThemeColour').val()
                    }
                    SaveEvent(data);
                })

SaveEvent function: Which saves the data

        function SaveEvent(data) {
            if (selectedEvent != null && confirm("Are you sure?")) {
                $.ajax({
                    type: "POST",
                    url: '/SessionScheduler/SaveEvent',
                    data: data,
                    success: function (data) {
                        if (data.status) {
                            //refresh the calendar if the status is true else its failed
                            FetchEventAndRenderCalendar();
                            $('#myModalSave').modal('hide'); //hide modal dialog pop window
                        }
                    },
                    error: function () {
                        alert('Failed');
                    }
                })
            }
        }
2 Answers

I did some search about this problem.

Everytime, they get all the events from the FC memory, and iterate over them, for searching conflict time.

Unfortunately, there is no simple solution for that.

My suggestions:

  1. You should to make a ajax call before every modification, where your server checks the conflict (if you store the events on the server side)
  2. If your server doesn't store your events, then you have to iterate all the events in the client side, in order to find a conflict.

This function will check whether the event passed in overlaps with any other events currently displayed on the calendar.

Note this relies on the events having unique id properties, so it doesn't check itself. It also cannot, by its nature, check any events not currently displayed on the calendar, because fullCalendar doesn't return those from its clientEvents method. You should check again on the server-side before accepting the modification into your database.

//check whether or not the calendar event passed in overlaps with an existing event in the current (client-side) calendar data
//the first parameter should be the event which is being tested
//the second parameter should be a jQuery object wrapping the calendar HTML element
function isCalendarEventOverlapping(event) 
{
    var evts = cal.fullCalendar('clientEvents');

    for (i in evts) 
    {
        if (evts[i].id != event.id)
        {
            if (event.start.isBefore(evts[i].end) && event.end.isAfter(evts[i].start))
            {
                return true;
            }
        }
    }
    return false;
}
Related