2012-03-11 16 views
5

Korzystając z fullCalendar, zezwalam użytkownikowi na wybór dnia w widoku miesiąca w dużym kalendarzu (#cal_big) i odpowiadającego mu małego kalendarza w widoku dnia, z podanymi godzinami (#cal_small) zostanie wyświetlony.fullCalendar 1.5.3 Utworzono wiele wydarzeń, nie można usunąć niezaznaczonych zdarzeń

Za każdym razem, gdy użytkownik wybierze wydarzenie (godzinę lub blok godzin) w #cal_small, wyświetli modulator potwierdzenia/anulowania. Modal potwierdzający/anulujący pozwala użytkownikowi potwierdzić rezerwację lub anulować rezerwację (co semantycznie oznacza, że ​​użytkownik tak naprawdę nie chce zarezerwować tego automatu).

The confirm or cancel modal window

Jeśli użytkownik potwierdza rezerwację, robię wywołanie ajax do serwera i rejestruje rezerwacji. Po pomyślnym powrocie wywołania ajax po prostu ukrywam bieżący modal i wyświetla "Twoja rezerwacja się udała!" wiadomość w nowym modalu. Ta część działa bezbłędnie.

Jeśli użytkownik anuluje rezerwację, modal potwierdzający/anulujący zostanie ukryty, a ja próbuję programowo usunąć zaznaczenie bieżącego wyboru i zaczyna się problem. Odznaczenie nie działa i wygląda na to, że fullCalendar zapamiętuje wszystkie selekcje, które nie są potwierdzone, a kiedy użytkownik ostatecznie potwierdza swój wybór, cała masa wcześniej niepotwierdzonych selekcji jest wysyłana do serwera wielokrotnie w wielu wywołaniach ajaxowych.

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

Dlaczego tak się dzieje i jak mogę zapobiec fullCalendar od pamiętając niepotwierdzone pozycje?

Oto kod: -

$(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

Funkcja confirmBooking na wniosek: -

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 

wdzięczny jeśli ktoś mógłby opracować dlaczego .fullCalendar ("odznaczyć ') nie działa, aby usunąć niepotwierdzone zdarzenia i jak mogę rozwiązać ten problem.

+2

Te "selekcje" nie wyglądają mi jak selekcje, wydają się być prawdziwymi wydarzeniami, które dodawane są do kalendarza gdzieś w funkcjach, które są wywoływane w twoim kodzie (np. ConfirmBooking lub checkAvailability) - czy jest gdziekolwiek połączenie z 'fullCalendar? ("renderEvent", ... "? – Niko

+0

Spodziewam się, że" poprzednia selekcja/wybrane wydarzenie "zostanie zniszczone co czas, gdy użytkownik kliknie gdzie indziej, w tym przycisk "anuluj" w modalu. Weryfikuję to nawet, próbując dołączyć wyraźne wywołanie zwrotne 'unselect', które wypisuje" zdarzenie niewybrane w #cal_small "," zdarzenie niezaznaczone w #cal_big "za każdym razem, gdy użytkownik kliknie gdzieś indziej niż przycisk potwierdzenia w modalu; i rzeczywiście, plik console.log drukuje te dzienniki. Jeśli te poprzednie zdarzenia są rzeczywiście niezaznaczone, dlaczego są one później traktowane jako część selekcji, gdy użytkownik ostatecznie "potwierdza"? –

+0

@Niko istnieje wywołanie metody 'fullCalendar ('renderEvent', event)', gdy wywołanie ajaxowania potwierdzającego na serwerze powraca pomyślnie, w celu renderowania określonego zdarzenia, które zostało potwierdzone. To, czego nie otrzymuję, jest przyczyną renderowania wcześniej niewybranego zdarzenia. –

Odpowiedz

7

Rozwiązał problem.

To martwy, prosty błąd, którego kompletnie przegapiłem.

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

powoduje zdarzenie click to być związany z przyciskiem #confirm każdym wydarzeniem jest wybrany w kalendarzu. Jeśli więc użytkownik wybierze zdarzenie bez potwierdzenia, przycisk #confirm będzie gromadził różne zdarzenia kliknięcia o różnych wartościach początkowej i końcowej. Kiedy użytkownik w końcu uderzy w przycisk #confirm po wielokrotnym niezdecydowaniu, wszystkie zdarzenia kliknięcia odpalą się za jednym razem, powodując, że wcześniej niewybrane zdarzenia będą wysyłane na serwer jako wiadomość ajaxowa.

Aby rozwiązać ten problem, muszę pamiętać, aby podać $('#confirm').unbind(), gdy użytkownik kliknie przycisk .cancel lub .close.

Argh ... proste rozwiązanie, ale zajęło mi to tyle czasu!

0

miałem ten sam problem, ale rozwiązać go za pomocą tego:

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

Gdybym wiedział o unbind wcześniej, wszystkie rzeczy, które musiałem zmienić nie byłaby konieczna :(

Powiązane problemy