2012-03-11 33 views
5

Sử dụng fullCalendar, tôi cho phép người dùng chọn một ngày trong chế độ xem theo tháng trong lịch lớn (#cal_big) và lịch nhỏ tương ứng trong chế độ xem theo ngày, với giờ được hiển thị (#cal_small) sẽ được hiển thị.fullCalendar 1.5.3 nhiều sự kiện được tạo, không thể xóa các sự kiện chưa được chọn

Bất cứ khi nào người dùng chọn sự kiện (giờ hoặc khối giờ) trong #cal_small, tôi sẽ hiển thị phương thức xác nhận/hủy. Phương thức xác nhận/hủy bỏ cho phép người dùng xác nhận đặt phòng hoặc hủy đặt phòng (theo nghĩa ngữ nghĩa là người dùng thực sự không muốn đặt chỗ đó sau tất cả).

The confirm or cancel modal window

Nếu người dùng xác nhận đặt phòng, tôi thực hiện cuộc gọi ajax đến máy chủ và đăng ký đặt phòng. Khi cuộc gọi ajax trở lại thành công, tôi chỉ cần ẩn phương thức hiện tại và hiển thị "Đặt chỗ của bạn thành công!" tin nhắn trong một phương thức mới. Phần này hoạt động hoàn hảo.

Nếu người dùng hủy đặt chỗ, xác nhận/hủy bỏ phương thức bị ẩn và tôi cố gắng bỏ chọn chương trình lựa chọn hiện tại và đây là nơi bắt đầu sự cố. Bỏ chọn không hoạt động và có vẻ như fullCalendar nhớ tất cả các lựa chọn không được xác nhận và khi người dùng cuối cùng xác nhận lựa chọn của mình, toàn bộ các lựa chọn chưa được xác nhận trước đó đều được gửi tới máy chủ nhiều lần trong nhiều cuộc gọi ajax.

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

Tại sao điều này như vậy và làm thế nào để ngăn chặn fullCalendar từ nhớ lựa chọn chưa được xác nhận?

Dưới đây là đoạn code: -

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

CẬP NHẬT

Chức năng confirmBooking theo yêu cầu: -

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 

Đánh giá cao nếu một số người ta có thể xây dựng tại sao .fullCalendar ('bỏ chọn ') cuộc gọi không hoạt động để loại bỏ các sự kiện chưa được xác nhận và cách tôi có thể giải quyết vấn đề này.

+2

Những "lựa chọn" không giống như các lựa chọn đối với tôi, chúng dường như là các sự kiện thực được thêm vào lịch ở đâu đó trong các hàm được gọi trong mã của bạn (như confirmBooking hoặc checkAvailability) - có bất kỳ nơi nào gọi đến 'fullCalendar ('renderEvent', ... '? – Niko

+0

Tôi hy vọng rằng 'sự lựa chọn trước đó/sự kiện được chọn' sẽ bị phá hủy mọi thời gian người dùng nhấp vào nơi khác, bao gồm nút 'hủy' trên phương thức. Tôi thậm chí xác minh nó bằng cách cố gắng bao gồm một lời gọi lại 'unselect' rõ ràng để in ra" sự kiện không được chọn trong #cal_small "," sự kiện không được chọn trong #cal_big "bất cứ khi nào người dùng nhấp vào một nơi nào khác ngoài nút xác nhận trong phương thức; và thực sự, console.log không in ra các bản ghi này. Nếu những sự kiện trước đó thực sự không được chọn, tại sao sau đó chúng được coi là một phần của lựa chọn khi người dùng cuối cùng "xác nhận"? –

+0

@Niko có một phương thức 'fullCalendar ('renderEvent', event)' gọi khi cuộc gọi confirmjooking ajax đến máy chủ trả về thành công, với mục đích hiển thị sự kiện cụ thể được xác nhận. Những gì tôi không nhận được là lý do tại sao sự kiện chưa được chọn trước đó cũng được hiển thị. –

Trả lời

7

Giải quyết.

Đó là một lỗi đơn giản mà tôi đã bỏ lỡ.

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

khiến sự kiện nhấp được ràng buộc với nút #confirm mỗi sự kiện được chọn trên lịch. Vì vậy, nếu người dùng tiếp tục chọn sự kiện mà không xác nhận, nút #confirm sẽ tiếp tục tích lũy các sự kiện nhấp chuột khác nhau với startDate và endDate khác nhau. Khi người dùng cuối cùng chạm vào nút #confirm sau khi lặp lại do dự, tất cả các sự kiện nhấp sẽ kích hoạt tại một thời điểm, dẫn đến các sự kiện chưa được chọn trước đó được gửi tới máy chủ dưới dạng bài đăng ajax.

Để giải quyết vấn đề này, tôi phải nhớ chỉ định $('#confirm').unbind() khi người dùng nhấp vào nút .cancel hoặc .close.

Argh ... một giải pháp đơn giản nhưng tôi mất quá nhiều thời gian để xem!

0

tôi đã cùng một vấn đề, nhưng tôi giải quyết nó bằng cách sử này:

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

Nếu tôi đã biết về unbind trước đó, tất cả những gì mà tôi đã phải thay đổi sẽ không có được cần thiết :(

Các vấn đề liên quan