Uso di fullCalendar, consento a un utente di selezionare una vista giorno in mese in un calendario grande (#cal_big) e il calendario piccolo corrispondente nella vista giorno, con ore visualizzate (#cal_small) verrà visualizzato.fullCalendar 1.5.3 più eventi creati, impossibile rimuovere gli eventi non selezionati
Ogni volta che l'utente seleziona un evento (un'ora o un blocco di ore) in #cal_small, verrà visualizzata una modale di conferma/annullamento. La modal di conferma/annullamento consente all'utente di confermare la prenotazione o di cancellare la prenotazione (che semanticamente significa che l'utente non vuole realmente prenotare quella fessura dopotutto).
Se l'utente conferma della prenotazione, mi fa una chiamata AJAX al server e registra la prenotazione. Una volta che la chiamata ajax viene restituita correttamente, nascondo semplicemente la modale corrente e visualizzo "La tua prenotazione è andata a buon fine!" messaggio in una nuova modal. Questa parte funziona perfettamente.
Se l'utente annulla la prenotazione, la modal di conferma/annullamento viene nascosta e si tenta di deselezionare a livello di codice la selezione corrente ed è qui che inizia il problema. La deselezione non funziona e sembra che fullCalendar ricordi tutte queste selezioni che non sono confermate e quando l'utente conferma definitivamente la sua selezione, una serie di selezioni precedentemente non confermate vengono inviate al server ripetutamente in più chiamate ajax.
Perché è così e come posso evitare di ricordare fullCalendar selezioni non confermate?
Ecco il codice: -
$(document).ready(function() {
var todayDate = new Date();
var myDate = todayDate.setDate(todayDate.getDate() - 1);
var csrfmiddlewaretoken = '{{ csrf_token }}';
var condo_slug = '{{ condo.slug }}';
var facility = $("#id_facility");
var cal_small_options = {
titleFormat: {
day: 'dddd'
},
header: {
left: '',
center:'title',
right:'',
},
height: 520,
defaultView: 'agendaDay',
editable: true,
minTime: '10:00',
maxTime: '23:00',
slotMinutes: 60,
selectable: true,
select: function(startDate, endDate, allDay, jsEvent, view) {
console.log("selection triggered", jsEvent.handleObj.guid)
checkAvailability(csrfmiddlewaretoken, condo_slug, facility, startDate, endDate);
$('#confirm').click(function(){
confirmBooking(csrfmiddlewaretoken, condo_slug, facility.val(), startDate, endDate)
});
},
events: function(start, end, callback) {
// start and end marks the current date range shown on the calendar
ajaxShowEvents(facility.val(), condo_slug, start, end, callback);
},
eventClick: function(event) {
console.log(event.title);
},
viewDisplay: function(view) {
// Clear the calendar and retrieve event objects when user selects a facility.
$('#id_facility').change(function(){
ajaxShowEvents(facility_id = $(this).val(), start = view.start, end = view.end);
});
}
};
var cal_big_options = {
header: {
left: '',
center:'title',
right: ''
},
dayClick: function(date, allDay, jsEvent, view) {
if (date < myDate) {
alert('You cannot book on this day!');
}
if (allDay) {
$('#cal_small').fullCalendar('gotoDate', date);
} else {
alert('Clicked on the slot: ' + date);
}
},
selectable: true,
unselectCancel: '',
events: function(start, end, callback) {
// start and end marks the current date range shown on the calendar
ajaxShowEvents(facility.val(), condo_slug, start, end, callback);
},
viewDisplay: function(view) {
// Clear the calendar and retrieve event objects when user selects a facility.
$('#id_facility').change(function(){
ajaxShowEvents(facility_id = $(this).val(), start = view.start, end = view.end);
});
},
eventClick: function(event, jsEvent, view) {
if(event.start < myDate) {
alert('You cannot book on this day!');
} else {
// check to see if the booking belongs to user
ajaxCheckBooking(csrfmiddlewaretoken, event);
$('#confirm').click(function(){
ajaxDeleteBooking(csrfmiddlewaretoken, event)
});
}
}
};
$('#cal_small').fullCalendar(cal_small_options);
$('#cal_big').fullCalendar(cal_big_options);
$('.cancel, .btn_close').click(function() {
$('#cal_big, #cal_small').fullCalendar('unselect')
$('#modal-window').modal('hide');
});
}); // END document ready
UPDATE
La funzione confirmBooking come richiesto: -
function confirmBooking(csrfmiddlewaretoken, condo_slug, facility_id, startDate, endDate) {
// Given condo slug, facility id and the user selected startDate and endDate,
// send an ajax post request to confirm the booking
post_data = {csrfmiddlewaretoken: csrfmiddlewaretoken,
condo_slug: condo_slug,
facility_id: facility_id,
start_date: startDate.toUTCString(),
end_date: endDate.toUTCString()}
$.ajax({
url: '/facility/ajax-confirm-booking/',
data: post_data,
type: 'POST',
dataType: 'json',
success: function(data) {
if (data['status']=='success') {
message = "Your booking is confirmed!"
event = new Object();
event.id = data['id'];
event.title = "Your Booked Event";
event.start = startDate;
event.end = endDate;
event.allDay = false;
$("#cal_big").fullCalendar('renderEvent', event);
$("#cal_small").fullCalendar('renderEvent', event);
// TODO:
// * disable the submit and reset buttons
// * email notification to end user and property manager
} else if (data['status']=='not logged in') {
message = "You are not yet logged in!"
// TODO:
// * Provide fb login button so user can login.
} else {
message = "I am sorry. Something went wrong with your booking"
// TODO:
// * Work on an email notification to site admin if a booking has failed for some reason
}
displayModal(message, false);
}
});
}; // END confirmBooking
grati se qualcuno potesse elaborare il motivo per cui il .fullCalendar ('unselect ') chiamata non funziona per rimuovere gli eventi non confermati e come posso risolvere questo problema.
Quelle "selezioni" non mi sembrano selezioni, sembrano essere eventi reali che vengono aggiunti al calendario da qualche parte in quelle funzioni che vengono invocate nel codice (come confirmBooking o checkAvailability) - c'è ovunque una chiamata a "fullCalendar" ('renderEvent', ... '? – Niko
Mi aspetto che la 'selezione precedente/evento selezionato' venga distrutta ogni tempo in cui l'utente fa clic altrove, incluso il pulsante 'cancella' sul modale. Lo verificherò anche provando ad includere un callback esplicito di 'unselect' che stampa" evento non selezionato in #cal_small "," evento non selezionato in #cal_big "ogni volta che l'utente fa clic in un punto diverso dal pulsante di conferma nel modale; e in effetti, console.log stampa questi log. Se quegli eventi precedenti sono effettivamente deselezionati, perché vengono considerati successivamente come parte della selezione quando l'utente finalmente "conferma"? –
@Niko c'è una chiamata al metodo 'fullCalendar ('renderingEvent', event)' quando la chiamata ajax confirmBooking al server ritorna correttamente, con lo scopo di rendere l'evento specifico che è confermato. Quello che non capisco è perché viene reso anche l'evento precedentemente non selezionato. –