首页 > 解决方案 > Fullcalendar 外部拖放无法正常工作

问题描述

我正在尝试实现这样的 Fullcalendar 功能:将外部事件拖到日历中,然后通过 ajax 将事件及其标题、开始和结束日期保存到数据库中。我确实实现了将事件标题和开始日期/时间保存到数据库,但是我无法解决以下几个问题:

  1. 目前,end保存到数据库的日期/时间与start日期/时间相同。
    • 如何将结束日期设置为全天活动开始日期后 24 小时?
    • 如何获得固定持续时间事件的确切日期start和日期?end
  2. 将事件拖放到数据库后,在按 F5 之前,我无法再拖放任何事件

我的 HML 如下:

<div id='external-events'>
   <div class="fc-events-container">
      <div>All Day Events</div>
      <div class='fc-event' data-color='#28A745'>All Day Event</div>
      <div>Fixed Duration Events</div>
      <div class='fc-event' data-color='#50C1E9'>Event From 8am till 5 pm</div>
   </div>
</div>

查询:

$('#external-drag').fullCalendar({
    header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek,agendaDay'
    },
    editable: true,
    droppable: true,
    defaultDate: new Date(),
    selectable: true,
    events: "../../ajax/get_events.php",

    drop: function( date, allDay, jsEvent, ui ) {
        var start =  date.format();
        var end =  date.format();
        var title = $.trim($(this).text()); 
            $.ajax({
                url: '../../ajax/add_event.php',
                data: 'title='+ title+'&start='+ start +'&end='+ end,
                type: "POST",
                success: function(json) {
                    alert('Added Successfully');
                },
                error: function() {
                    alert('Error');
                }
            });
            calendar.fullCalendar('renderEvent',
            {
                title: title,
                start: start,
                end: end,
                allDay: allDay
            },
            true
        );
    }

});

标签: javascriptjquery-uifullcalendarjquery-ui-draggablefullcalendar-3

解决方案


首先,您所经历的一些背景背景:尽管您将第二个事件标记为“从晚上 8 点到下午 5 点”,但这并没有实际的实际效果。如果您将一可拖动项目拖放到时间感知日历视图(例如周视图)上,则它将获得开始日期和时间。在诸如月份之类的视图上,它没有一天中特定时间的概念,那么它将只获得一个开始日期,而没有附加时间。

但是,在这两种情况下,都没有结束日期。通过renderEvent将事件添加到日历后,fullCalendar 将为其分配默认持续时间(根据 defaultAllDayEventDurationdefaultTimedEventDuration设置,视情况而定)。您可以使用它来计算名义上的结束日期(尽管事件对象实际上并没有end设置其属性,除非您将forceEventDuration设置为true)。


现在来一个解决方案:

如果您想控制它以使特定的拖动项具有预定义的时间,则必须data-在相关可拖动项的属性中指定时间数据。然后,您需要在drop回调中获取这些值,就像使用标题一样,并在创建事件时使用它们。

达到这一点需要一些摆弄,尤其是对于时刻对象,但它现在似乎可以做你想做的事——据我所知。

drop: function(date, jsEvent, ui) {
  var element = $(this);
  var title = $.trim(element.text());
  var color = element.data("color");
  var start = moment(date.format()); //lose the extended fullCalendar moment with its "ambiguously-timed" feature, which gets in the way here
  var end = start.clone();
  var allDay = true;
  console.log(start.format(), end.format());
  if (typeof element.data("starttime") !== 'undefined') {
    //timed events
    var starttime = moment.duration(element.data("starttime"));
    var endtime = moment.duration(element.data("endtime"));
    start.set({ "hour": starttime.hours(), "minute": starttime.minutes()});
    end.set({ "hour": endtime.hours(), "minute": endtime.minutes()});
    allDay = false;
    console.log(starttime.hours());
  } else {
    //allday events
    end.add({ days: 1 });
  }
  console.log("title=" + title + "&start=" + start.format() + "&end=" + end.format());
  $.ajax({
            url: '../../ajax/add_event.php',
            data: 'title='+ title+'&start='+ start.format() +'&end='+ end.format(),
            type: "POST",
            success: function(json) {
                alert('Added Successfully');
            },
            error: function() {
                alert('Error');
            }
        });
  calendar.fullCalendar(
    "renderEvent",
    {
      title: title,
      start: start,
      end: end,
      color: color,
      allDay: allDay
    },
    true
  );
}

演示:https ://codepen.io/ADyson82/pen/GRRXwRL?editors=1010

NB 请注意,如果用户将事件拖到像周视图这样的时间感知视图上,它仍将完全按照可拖动对象中的设置创建事件,并且将忽略他们将其放在一天中的任何时间。这可能会让一些用户感到困惑或恼火——但我想这取决于你想要达到的目标。

PS我不知道你从哪里得到drop回调有allDay参数的想法。文档中显然没有。你不能使用它,所以我在我的版本中删除了它。


推荐阅读