2012-03-11 9 views
5

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).

The confirm or cancel modal window

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.

Multiple Events created even though the previous two events ought to have been unselected

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.

+2

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

+0

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"? –

+0

@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. –

risposta

7

Risolto.

Si tratta di un bug semplice e morto che ho completamente perso.

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) 
     }); 
    }, 

provoca un evento click ad essere vincolato al pulsante #confirm ogni volta un evento è selezionato sul calendario. Pertanto, se l'utente continua a selezionare l'evento senza confermare, il pulsante #confirm continuerà ad accumulare eventi di clic diversi con date di inizio e fine differenti. Quando l'utente alla fine colpisce il pulsante #confirm dopo un'indecisione ripetuta, tutti gli eventi di clic vengono attivati ​​contemporaneamente, con la conseguenza che gli eventi precedentemente non selezionati vengono inviati al server come post ajax.

Per risolvere questo problema, devo ricordare di specificare $('#confirm').unbind() quando l'utente fa clic sul pulsante .cancel o .close.

Argh ... una soluzione semplice ma mi ci è voluto così tanto tempo per vederlo!

0

Ho avuto lo stesso problema, ma ho risolto con questo:

$("#confirm").dialog({... 

Se avessi saputo unbind in precedenza, tutte le cose che ho dovuto cambiare non sarebbero state necessarie :(

Problemi correlati