2012-03-11 74 views
5

使用fullCalendar,我允許用戶選擇大日曆(#cal_big)中的月視圖中的日期和日視圖中的相應小日曆,並顯示小時(#cal_small)將會顯示。fullCalendar 1.5.3創建了多個事件,無法刪除未選定的事件

每當用戶在#cal_small中選擇一個事件(一小時或幾小時),我將顯示一個確認/取消模式。確認/取消模式允許用戶確認預訂或取消預訂(這在語義上意味着用戶並不真的想要預訂那個位置)。

The confirm or cancel modal window

如果用戶確認的預訂,我做一個AJAX調用服務器並註冊預訂。一旦ajax調用成功返回,我只需隱藏當前的模式並顯示「您的預訂成功!」消息在一個新的模式。這部分工作完美無瑕。

如果用戶取消預訂,確認/取消模式將被隱藏,並且我試圖以編程方式取消選擇當前選擇,這是問題開始的地方。 unselect不起作用,並且看起來fullCalendar記住所有這些未被確認的選擇,並且當用戶最終確認他的選擇時,一大堆以前未經確認的選擇全部通過多個ajax調用被重複發送到服務器。

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

爲什麼會這樣?我如何防止fullCalendar從記憶未經證實的選擇?

下面的代碼: -

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

的confirmBooking功能的要求: -

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 

感激,如果有人能解釋一下爲什麼.fullCalendar(「取消選擇')呼叫不起作用去除未經證實的事件,並且我怎麼能解決這個問題。

+2

這些「選擇」看起來不像我的選擇,他們似乎是真正的事件,被添加到在你的代碼中調用的那些函數中的某個地方的日曆中(像confirmBooking或checkAvailability) - 是否有任何地方調用'fullCalendar ('renderEvent',...'? – Niko 2012-03-11 14:17:54

+0

我期待每一次'選擇/選擇事件'被銷燬用戶點擊其他地方的時間,包括模式上的「取消」按鈕。我甚至通過試圖包含一個明確的'unselect'回調來驗證它,只要用戶點擊模式中的確認按鈕以外的地方,就會打印出「未在#cal_small中選擇的事件」,「在#cal_big中未選中的事件」事實上,console.log確實打印出這些日誌。如果這些先前的事件確實未被選中,那麼爲什麼當用戶最終「確認」後,他們以後會被視爲選擇的一部分? – 2012-03-13 13:40:03

+0

@Niko當confirmBooking對服務器的Ajax調用成功返回時,有一個'fullCalendar('renderEvent',event)'方法調用,目的是渲染已確認的特定事件。我沒有得到的是爲什麼以前未選中的事件也被呈現。 – 2012-03-13 14:55:40

回答

7

解決了它。

這是一個死的簡單的錯誤,我完全錯過了。

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

導致點擊事件被綁定到#confirm按鈕每次被在日曆中選擇的事件。因此,如果用戶在未經確認的情況下繼續選擇活動,那麼#confirm按鈕將使用不同的startDate和endDate持續累積不同的點擊事件。當用戶最終在反覆優化後碰到#confirm按鈕時,所有的點擊事件都會一次性觸發,導致之前未選中的事件作爲ajax帖子發送到服務器。

要解決這個問題,我必須記得在用戶點擊.cancel.close按鈕時指定$('#confirm').unbind()

呃...一個簡單的解決方案,但它花了我很長時間纔看到它!

0

我有同樣的問題,但我解決它使用這樣的:

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

早知早約unbind,所有我不得不改變的事情不會有必要:(