You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FullCalendar 3.8.0在AngularJS中无法实现单日事件垂直拖拽排序

解决AngularJS + FullCalendar 3.8.0中basicWeek视图单日事件垂直拖拽排序问题

Got it, let's tackle this problem—you need to enable vertical drag-and-drop reordering for all-day events within the same day in FullCalendar 3.8.0's basicWeek view, right? The default FullCalendar drag functionality only lets you move events between dates, not reorder them on the same day. Here's how to make it work with your existing AngularJS + ngDraggable + ui-calendar setup:

核心思路

FullCalendar's eventOrder config lets you control event display order. We'll add a custom sortOrder field to each event, update this value when dragging, and tell FullCalendar to use this field for sorting. This way, dragging an event will adjust its position by modifying its sortOrder and re-rendering the calendar.

具体实现步骤

1. Add a custom sort field to events

First, add a sortOrder property to all your events (both initial dummy data and draggable objects) to track their display order:

// Dummy event data with sortOrder
var eventEntities = [
    { 
        title : "Job Name One- #H", 
        description : "Operation New Submittaly", 
        start : $scope.droppableObjectsDate , 
        end : $scope.droppableObjectsDate , 
        allDay : true,
        sortOrder: 1 // Initial sort position
    } , 
    { 
        title : "Long Lead Time Name 2- #H", 
        description : "Operation New Submittaly", 
        start : $scope.droppableObjectsDate , 
        end : $scope.droppableObjectsDate , 
        allDay : true,
        sortOrder: 2
    }
];

// Draggable objects with sortOrder
$scope.draggableObjects = [
    { 
        title : "Job Name One- #H", 
        description : "Operation New Submittal", 
        start: $scope.droppableObjectsDate, 
        end : $scope.droppableObjectsDate, 
        allDay : true,
        sortOrder: 3
    }, 
    { 
        title : "Long Lead Time Name 2- #H", 
        description : "Operation New Submittal", 
        start : $scope.droppableObjectsDate, 
        end : $scope.droppableObjectsDate, 
        allDay : true,
        sortOrder: 4
    }
];

2. Configure FullCalendar to use the custom sort field

Update your uiConfig.calendar settings to sort events by the sortOrder field:

$scope.uiConfig = {
    calendar : {
        // ... keep your existing config
        eventOrder: "sortOrder", // Use our custom sort field
        // ... keep your existing config
    }
}

3. Handle drag-and-drop for same-day events

Modify the eventDrop and onDropComplete1 methods to handle same-day reordering. We'll calculate the new sort position based on the drag target and update the event's sortOrder.

First, update the eventDrop handler for internal calendar events:

eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc, jsEvent, ui, view){
    // Check if we're dragging within the same day (no day change, all-day event)
    if (dayDelta === 0 && allDay) {
        // Get all events on the same day
        var sameDayEvents = $scope.events.filter(e => 
            moment(e.start).isSame(event.start, 'day')
        );
        var targetElement = $(jsEvent.target).closest('.fc-event');
        var siblingEvents = targetElement.siblings('.fc-event');
        var targetSortOrder;

        // Determine drag direction (up/down)
        if (ui.position.top < targetElement.offset().top) {
            // Dragging up: set sortOrder to just above the previous event
            var prevEvent = siblingEvents.filter((i, el) => $(el).offset().top < ui.position.top).last();
            targetSortOrder = prevEvent.length ? prevEvent.data('event').sortOrder - 0.5 : 0;
        } else {
            // Dragging down: set sortOrder to just below the next event
            var nextEvent = siblingEvents.filter((i, el) => $(el).offset().top > ui.position.top).first();
            targetSortOrder = nextEvent.length ? nextEvent.data('event').sortOrder + 0.5 : sameDayEvents.length + 1;
        }

        // Update the event's sort order and re-render
        event.sortOrder = targetSortOrder;
        uiCalendarConfig.calendars.myCalendar.fullCalendar('rerenderEvents');
    }
}

Then, update onDropComplete1 for external events dragged into the calendar:

$scope.onDropComplete1 = function(data, evt) {
    var index = $scope.events.indexOf(data);
    if (index == -1) {
        // Get all events on the drop date
        var sameDayEvents = $scope.events.filter(e => 
            moment(e.start).isSame(evt.start, 'day')
        );
        // Set new event's sort order to the highest existing +1
        data.sortOrder = sameDayEvents.length > 0 ? 
            Math.max(...sameDayEvents.map(e => e.sortOrder)) + 1 : 
            1;
        data.start = evt.start;
        data.end = evt.start;
        $scope.events.push(data);
        // Re-render to apply the new order
        uiCalendarConfig.calendars.myCalendar.fullCalendar('rerenderEvents');
    }
}

4. Bind events to DOM elements for drag handling

Update the eventRender method to attach the event object to its DOM element (so we can access it during drag operations):

// Don't forget to inject $compile into your controller dependencies!
eventRender: function(event, element, view){
    element.data('event', event); // Bind event data to the DOM element
    // Add ng-drag attributes to enable internal drag (compile to activate Angular directives)
    element.attr('ng-drag', 'true').attr('ng-drag-data', 'event');
    $compile(element)($scope);
}

5. Clean up your HTML template

Remove the extra ng-repeat inside the calendar container—FullCalendar handles event rendering internally, and this duplicate binding will cause conflicts:

<div>
    <div id="calendar_one" 
         ng-drop-success="onDropComplete1($data,$event)" 
         ui-calendar="uiConfig.calendar" 
         ng-model="eventSources" 
         calendar="myCalendar">
    </div>
</div>

Key Notes

  • Using decimal values for sortOrder avoids having to re-number all events when inserting a new one—we just slot the dragged event between existing values.
  • Always call rerenderEvents after updating sortOrder to tell FullCalendar to refresh the event display.
  • We use Moment.js to reliably check if events are on the same day.

内容的提问来源于stack exchange,提问作者Venkatesh Mulka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:47:58