FullCalendar实现可展开层级事件(Drilldown Event)方案咨询
Absolutely! You can absolutely build this drilldown event functionality in FullCalendar—here's a practical, step-by-step solution that fits your exact use case:
First, add metadata to your events to distinguish parent events from their children. We’ll use isParent: true for parent events, and a parentId on child events to link them to their parent. We’ll also default child events to be hidden initially:
const events = [ // Parent Events { id: 'event1', title: 'EVENT 1', start: '2024-05-20', extendedProps: { isParent: true } }, { id: 'event2', title: 'EVENT 2', start: '2024-05-20', extendedProps: { isParent: true } }, // Child Events (initially hidden) { id: 'event1-child1', title: 'event 1的子集', start: '2024-05-20T09:00:00', display: 'none', extendedProps: { parentId: 'event1' } }, { id: 'event1-child2', title: 'event 1的子集', start: '2024-05-20T14:00:00', display: 'none', extendedProps: { parentId: 'event1' } }, { id: 'event2-child1', title: 'event 2的子集', start: '2024-05-20T10:00:00', display: 'none', extendedProps: { parentId: 'event2' } }, { id: 'event2-child2', title: 'event 2的子集', start: '2024-05-20T15:00:00', display: 'none', extendedProps: { parentId: 'event2' } } ];
Next, initialize your calendar with an eventClick handler. This handler will:
- Only respond to clicks on parent events
- Toggle the visibility of the clicked parent’s children
- Collapse any previously expanded parent’s children to keep the view clean
// Track which parent event is currently expanded let currentExpandedParent = null; document.addEventListener('DOMContentLoaded', function() { const calendarEl = document.getElementById('calendar'); const calendar = new FullCalendar.Calendar(calendarEl, { initialView: 'dayGridMonth', events: events, eventClick: function(info) { // Ignore clicks on child events if (!info.event.extendedProps.isParent) return; const clickedParentId = info.event.id; // If clicking the already expanded parent, collapse its children if (clickedParentId === currentExpandedParent) { toggleChildVisibility(clickedParentId, 'none'); currentExpandedParent = null; } else { // Collapse the previous expanded parent's children first if (currentExpandedParent) { toggleChildVisibility(currentExpandedParent, 'none'); } // Expand the clicked parent's children toggleChildVisibility(clickedParentId, 'auto'); currentExpandedParent = clickedParentId; } } }); calendar.render(); }); // Helper function to show/hide child events for a given parent function toggleChildVisibility(parentId, displayState) { const calendar = FullCalendar.getCalendar('calendar'); // Find all child events linked to the parent const childEvents = calendar.getEvents().filter(event => event.extendedProps.parentId === parentId ); // Update each child's display state childEvents.forEach(child => { child.setProp('display', displayState); }); }
Add some CSS to make parent events stand out visually, so users know they’re clickable:
/* Make all events feel interactive */ .fc-event { cursor: pointer; } /* Style parent events with a distinct look */ .fc-event[data-is-parent="true"] { background-color: #2d3748; border-color: #2d3748; font-weight: bold; }
If your events are loaded from an API instead of being hardcoded, just make sure your backend returns the isParent and parentId properties in the event objects. You can then pass the fetched data directly to the calendar’s events option, and the drilldown logic will work the same way.
This setup will give you exactly what you want: clicking EVENT 1 shows its two children (while keeping EVENT 2 visible but collapsed), clicking EVENT 2 will collapse EVENT 1’s children and show its own, and clicking an expanded parent again will collapse its children.
内容的提问来源于stack exchange,提问作者Piero Borrelli

