【问题标题】:fullCalendar 1.5.3 multiple events created, unable to remove unselected eventsfullCalendar 1.5.3 创建了多个事件,无法删除未选择的事件
【发布时间】:2013-07-08 08:42:46
【问题描述】:

使用 fullCalendar,我允许用户在大日历 (#cal_big) 中选择月视图中的一天,并在日视图中选择相应的小日历,并显示小时数 (#cal_small)。

每当用户在#cal_small 中选择一个事件(一个小时或几个小时)时,我都会显示一个确认/取消模式。确认/取消模式允许用户确认预订或取消预订(这在语义上意味着用户根本不想预订那个时段)。

如果用户确认预订,我会向服务器发出 ajax 调用并注册预订。一旦 ajax 调用成功返回,我只需隐藏当前模式并显示“您的预订成功!”新模式中的消息。这部分工作完美。

如果用户取消预订,确认/取消模式将被隐藏,我尝试以编程方式取消选择当前选择,这就是问题开始的地方。取消选择不起作用,并且似乎 fullCalendar 记住了所有这些未确认的选择,当用户最终确认他的选择时,一大堆以前未确认的选择都在多个 ajax 调用中重复发送到服务器。

为什么会这样?如何防止 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

更新

按要求的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('unselect') 调用无法删除未确认的事件,以及我如何解决这个问题。

【问题讨论】:

  • 那些“选择”在我看来不像是选择,它们似乎是真实的事件,会在代码中调用的那些函数(如 confirmBooking 或 checkAvailability)中的某个地方添加到日历中 -有什么地方可以打电话给fullCalendar('renderEvent', ...吗?
  • 我希望每次用户点击其他地方时都会销毁“先前的选择/选定事件”,包括模式上的“取消”按钮。我什至通过尝试包含一个显式的unselect 回调来验证它,只要用户单击模式中的确认按钮以外的其他位置,它就会打印出“#cal_small 中未选择的事件”、“#cal_big 中未选择的事件”;事实上,console.log 确实会打印出这些日志。如果这些之前的事件确实没有被选中,为什么在用户最终“确认”时它们被视为选择的一部分?
  • @Niko 有一个fullCalendar('renderEvent', event) 方法在对服务器的confirmBooking ajax 调用成功返回时调用,目的是呈现被确认的特定事件。我不明白为什么还会渲染先前未选择的事件。
  • 您介意发布您的confirmBooking 函数的代码吗?
  • 您好@Niko 上面粘贴的代码。感谢您帮助我解决这个问题!

标签: jquery fullcalendar


【解决方案1】:

解决了。

这是一个非常简单的错误,我完全错过了。

   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 post发送到服务器。

为了解决这个问题,我必须记得在用户点击.cancel.close 按钮时指定$('#confirm').unbind()

啊……一个简单的解决方案,但我花了很长时间才看到它!

【讨论】:

    【解决方案2】:

    我有同样的问题,但我用这个解决了它:

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

    如果我早点知道unbind,那么我必须改变的所有事情都没有必要了:(

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      相关资源
      最近更新 更多