使用特定持续时间在fullCalendar组件中拖动事件

时间:2012-09-23 13:32:04

标签: drag-and-drop fullcalendar

我见过drag and drop external events in fullcalendar的解决方案。但是,在此演示中,所有外部事件的持续时间为2小时(因为defaultEventMinutes参数设置为120)。我正在尝试更改此演示,以便管理具有不同持续时间的事件。说,“我的事件1”长45分钟,“我的事件2”是165分钟等等。

开头我虽然可能有一个属性来存储eventObject中的持续时间,但根据文档,情况并非如此。 然后,我认为在开始拖动事件时可以更改'defaultEventMinutes'的值。但显然,如果不重建整个日历,我就无法做到。

据您了解,满足此要求的最佳方法是什么? 提前感谢您的建议...

7 个答案:

答案 0 :(得分:3)

也是这样做的,并以这种方式解决了fullCalendar上显示的持续时间:

  1. 为fullCalendar设置自定义“setOptions”。
  2. 拥有一个名为“dragMinutes”的fullCalendar属性,可以在元素$(this).draggable({start:...})中设置。
  3. 以下是自定义setOptions的代码:

     ...
        function Calendar(element, options, eventSources) {
            var t = this;
    
            // hack for setting options that updates
            function setOptions(new_options, refresh) {
                $.extend(options, new_options);
                if (refresh) {
                    var viewName = currentView.name;
                    changeView(viewName, true);
                }
            }
        // exports ... 
        t.setOptions = setOptions;
        ...
    

    下面是处理fullCalendar中“dragMinutes”选项的代码:

    /* External Dragging
    --------------------------------------------------------------------------------*/
    
    
    function dragStart(_dragElement, ev, ui) {
        hoverListener.start(function (cell) {
            clearOverlays();
            if (cell) {
                if (cellIsAllDay(cell)) {
                    renderCellOverlay(cell.row, cell.col, cell.row, cell.col);
                } else {
                    var d1 = cellDate(cell);
                    if (opt('dragMinutes'))
                        var d2 = addMinutes(cloneDate(d1), opt('dragMinutes'));
                    else
                        var d2 = addMinutes(cloneDate(d1), opt('defaultEventMinutes'));
                    renderSlotOverlay(d1, d2);
                }
            }
        }, ev);
    }
    

    以下是我如何使事件可拖动并更新“dragMinutes”:

        // make the event draggable using jQuery UI
        $(this).draggable({
            containment: 'document',
            // return a custom styled elemnt being dragged
            helper: function (event) {
                return $('<div class="uv-planning-dragging"></div>').html($(this).html());
            },
            opacity: 0.70,
            zIndex: 10000,
            appendTo: 'body',
            cursor: 'move',
            revertDuration: 0,
            revert: true, 
            start: function (e, ui) {
                // set the "dragMinutes" option in fullCalendar so shown interval about to be added is correct.
                var data = $(this).data('eventObject');
                if (data) {
                    var min = data.jsonProps.durationMsec / 1000 / 60;
                    if (macroCalendar.calendar) {
                        macroCalendar.calendar.fullCalendar('setOptions', { dragMinutes: Math.round(min) }, false);
                    }
                }
            },
            stop: function (e, ui) {
                // further process
    
            }
        });
    

    希望它有所帮助。

答案 1 :(得分:2)

目前,我找到的最佳解决方案是在我的事件对象上添加 duration 属性,然后创建我的fullCalendar的代码如下所示:

    $('#calendar').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        editable: true,
        droppable: true, // this allows things to be dropped onto the calendar !!!
        drop: function(date, allDay) { // this function is called when something is dropped

            // retrieve the dropped element's stored Event Object
            var originalEventObject = $(this).data('eventObject');

            // we need to copy it, so that multiple events don't have a reference to the same object
            var copiedEventObject = $.extend({}, originalEventObject);

            // assign it the date that was reported
            copiedEventObject.start = date;
            // HERE I force the end date based on the start date + duration
            copiedEventObject.end = new Date(date.getTime() + copiedEventObject.duration * 60 * 1000);
            copiedEventObject.allDay = allDay;

            // render the event on the calendar
            // the last `true` argument determines if the event "sticks" (http://arshaw.com/fullcalendar/docs/event_rendering/renderEvent/)
            $('#calendar').fullCalendar('renderEvent', copiedEventObject, true);

            // is the "remove after drop" checkbox checked?
            if ($('#drop-remove').is(':checked')) {
                // if so, remove the element from the "Draggable Events" list
                $(this).remove();
            }

        }
    });

唯一的缺点是当您拖动事件时,事件持续时间看起来像 defaultEventMinutes 而不是实际持续时间,但我不知道如何解决它

答案 2 :(得分:1)

如果有人仍然访问该主题并且找不到解决方案,解决方法是在事件div中设置duration参数...然后在该div上调用draggable。

$(this).data('event', {
    title: 'new event title', // use the element's text as the event title
    id: $(this).attr('id'),
    stick: true, // maintain when user navigates (see docs on the renderEvent method)
    duration: '03:00:00' // will set the duration during drag of event
});

答案 3 :(得分:1)

可以在提供的事件对象中指定这些特殊属性,也可以将它们设置为独立的数据属性:

<!-- DURATION OF 3 hours EVENT WILL PROPAGATE TO CALENDAR WHEN DROPPED -->
<div class='draggable' data-event='1' data-duration='03:00' />

https://fullcalendar.io/docs/dropping/eventReceive/

答案 4 :(得分:0)

使用最新的defaults write,如果您希望叠加层具有特定的持续时间,则可以使用defaults write ~/Path/To/Info.plist CFBundleURLTypes -array-add '<dict><key>CFBundleURLName</key><string>urlname-1</string><key>CFBundleURLSchemes</key><array><string>urlscheme-1</string></array></dict>'

的此功能进行更新
fullcalendar v2.0.2

在这里,在外部事件对象和您可以在fullcalendar-arshaw.js中获取的对象中传递持续时间,然后将其转换为毫秒并在function dragStart(_dragElement, ev, ui) { hoverListener.start(function(cell) { clearOverlays(); if (cell) { var seconds = duration_in_minutes * 1000 * 60 ; // we need to pass seconds into milli-seconds if (d1.hasTime()) { d2.add(seconds); renderSlotOverlay(d1, d2, cell.col); } else { d2.add(calendar.defaultAllDayEventDuration); renderDayOverlay(d1, d2, true, cell.col); } } }, ev); } 中传递。这将在该日历上创造出那个mili-seconds的影子。

答案 5 :(得分:0)

对于非外部事件,您可以使用fullcalendar设置:

defaultTimedEventDuration: (hours+':00:00'),
forceEventDuration: true,
// defaultEventMinutes: hours*60, // not needed

并且在事件数据中,您没有设置结束属性(或者将其置空):

eventData = {
    title: title,
    start: start,
    // end: end, // MUST HAVE no end for fixedduration
    color: '#00AA00',
    editable: true, // for dragging
};

参考:http://fullcalendar.io/docs/event_data/defaultTimedEventDuration/

提示:如果您想阻止调整editable: true导致的事件大小,可以使用CSS隐藏句柄:.fc-resizer.fc-end-resizer { display:none; }

答案 6 :(得分:0)

自v4以来,上述某些选项根本无法使用。我面临的问题如下:

对我来说,一整天的物品都有持续时间,但没有开始时间。当我通过拖动选择开始时间时,将设置开始时间,但是一旦我设置了结束日期(操作与上述答案类似),结束日期就会再次重置.. setDate中发生了一些错误功能...设置结束日期,这部分工作,然后它会进行自我比较以找出日期之间的时差,但是系统本身已经设置了日期,导致时差为0,这导致结束日期再次设置为null ...

我不得不说我脖子上的巨大疼痛...在时间表内停留时效果很好,仅此而已。

我设法'修复',更像是在eventDrop事件中使用此行来销毁它,但它也可以在您可能使用的任何其他事件中使用:

  • 在这里用ajax更新您的活动,因为您有开始和结束日期*
  • calendar.refetchEvents();在成功功能中

这将重新获取所有事件,这听起来像是性能的杀手but,但似乎并不需要花费很多时间,您可以自己尝试一下。 这样,我的标题,时间等总是保持最新状态,日历显示正确的结束日期。