之前的预订是由 php 代码元素定义的。参数 eventOverlap 和 selectOverlap 为 false,但我有重叠的事件。
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var reservations = [
<?php
foreach ($reservations as $index => $reservation) {
if ($index > 0) echo ',';
echo "{
start: '{$reservation['date_debut']}',
end: '{$reservation['date_fin']}',
backgroundColor: 'red',
rendering: 'background'
}";
}
?>
];
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
selectable: true,
selectOverlap: function(event) {
return !event.rendering;
},
events: reservations,
eventOverlap: false,
selectOverlap: false,
select: function(info) {
var isConflict = reservations.some(function(reservation) {
var reservationStart = new Date(reservation.start).getTime();
//var reservationEnd = new Date(reservation.end).getTime() - 86400000; // Soustraire 1 jour
var reservationEnd = new Date(reservation.end).getTime();
var selectedStart = new Date(info.startStr).getTime();
//var selectedEnd = new Date(info.endStr).getTime() - 86400000; // Soustraire 1 jour
var selectedEnd = new Date(info.endStr).getTime();
return selectedStart <= reservationEnd && selectedEnd >= reservationStart;
});
if (isConflict) {
alert('Erreur : la période sélectionnée chevauche une réservation existante.');
calendar.unselect();
} else {
document.getElementById('date_debut').value = info.startStr;
// Mise à jour correcte de la date de fin sans soustraction supplémentaire
document.getElementById('date_fin').value = info.endStr;
}
},
validRange: {
start: new Date().toISOString().split('T')[0] // Désactiver les sélections dans le passé
},
unselectAuto: false
});
calendar.render();
不要使用 eventOverlap: false 或 selectOverlap: false。相反,在 select 函数调用的 saveevent 函数中处理冲突。
//This function fires when a free timeslot is clicked in the calendar
select: function(info) {
console.log('selected ' + info.startStr + ' to ' + info.endStr);
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
var date = new Date(info.start);
// example: Saturday, September 17, 2016
var formatteddate=date.toLocaleTimeString("en-US", options)
document.getElementById("formatteddate").value = formatteddate;
document.getElementById("hour").value = info.startStr;
saveevent();
}
保存事件
function saveevent(event) {
console.log("save an event");
const user_id = JSON.parse(document.getElementById('user_id').textContent);
const servicelist = document.getElementById('servicelist').value;
const eventstart = document.getElementById("hour").value;
const totalminutes = document.getElementById("totalminutes").textContent;
console.log("hour:" + eventstart );
fetch('/saveevent', {
method: 'PUT',
credentials:'include',
body: JSON.stringify({
userid: user_id,
eventstart:eventstart,
servicelist:servicelist,
totalminutes:totalminutes,
})
})
.then(response => response.json())
.then(result => {
// Print result
console.log(result);
if(result.message=="event saved successfully.")
{
document.getElementById("errormessage").innerHTML="";
calendar.refetchEvents();
}
else
{
document.getElementById("errormessage").innerHTML=result.message;
}
});
};
python函数
def saveevent(request):
if request.method == "PUT":
# Get contents of event
data = json.loads(request.body)
startdate_str = data.get("eventstart", "")
servicelist=data.get("servicelist", "")
user = User.objects.get(id=request.user.id)
totalminutes=data.get("totalminutes", "")
start_date_obj = parse(startdate_str)
end_date_obj = start_date_obj + timedelta(minutes=int(totalminutes) )
print('saveevent view called for user id: ' + str(request.user.id) + ' startdate:' + str(startdate_str) + ' services ' + str(servicelist) )
now_obj=datetime.now(tz=timezone.utc)
earlieststart=now_obj + timedelta(hours=int(22) )
earlieststart_str = earlieststart.strftime('%A, %B %d at %I:%M %p')
if start_date_obj < earlieststart:
#Not enough advanced notice. Earliest start time is Tuesday, November 17 at 10am.
return JsonResponse({"message": "Not enough advanced notice. Earliest start time is " + earlieststart_str }, status=201)
else:
#A conflict occurs in 2 possible scenarios:
#1. The proposed start date falls within the start-end times of any existing event
StartDateConflicts = Event.objects.filter(start_date__gt=startdate_str,start_date__lt=end_date_obj)
#2. The proposed end date falls within the start-end times of any existing event
EndDateConflicts = Event.objects.filter(end_date__gt=startdate_str,end_date__lt=end_date_obj)
conflictingevents = StartDateConflicts | EndDateConflicts
if conflictingevents:
return JsonResponse({"message": "event conflics with " + str(conflictingevents.count()) + " other events on schedule"}, status=201)
else:
#datetime.strptime(startdate_str, '%Y-%m-%d %H:%M:%S.%f')
fiveMinutesAgo = now_obj - timedelta(minutes=5)
#delete all unconfirmed events for the user
Event.objects.filter(owner_id=user.id, confirmed=False).delete()
event = Event(
event_name=user.username,
start_date=start_date_obj,
end_date=end_date_obj,
owner_id=user.id,
create_date=now_obj,
)
event.save()
print('event Saved:' + user.username + ' ' + startdate_str)
return JsonResponse({"message": "event saved successfully."}, status=201)
else:
return JsonResponse({"message": "Invalid request method. POST method expected."}, status=400)