FullCalendar 3.9.0 仅为含事件日期添加自定义div的技术实现求助
Hey there! Let's fix this FullCalendar 3.9.0 customization for you. You want to add a custom div only to dates that have events, right? Your previous attempts were close but missed a couple key pieces—like using FullCalendar's built-in hooks to ensure timing is right, and properly targeting only the days with events.
Here's a complete, working solution tailored to your needs:
Step 1: Use FullCalendar's eventAfterAllRender Hook
The biggest issue with your earlier jQuery code was timing—you were trying to modify the DOM before FullCalendar finished rendering events. FullCalendar has a built-in callback eventAfterAllRender that runs after all events are fully drawn, which is perfect for this task.
Step 2: Full Working Code
This includes your resource data, FullCalendar initialization, and the custom div logic:
jQuery(document).ready(function() { // Your existing resource event data const resourceEvents = [ { "item1": { "Resource_Id": "56", "Days": "1", "Hours":"8" } }, { "item2": { "Resource_Id": "56", "Days": "1", "Hours":"1" } }, { "item3": { "Resource_Id": "57", "Days": "1", "Hours":"4" } }, { "item4": { "Resource_Id": "57", "Days": "1", "Hours":"4" } } ]; // Initialize your FullCalendar instance $('#calendar').fullCalendar({ // Add your existing calendar options here (resources, events, view type, etc.) resources: [ { id: '56', title: 'Resource 56' }, { id: '57', title: 'Resource 57' } ], events: [ // Make sure your events link to the correct resource IDs { resourceId: '56', start: '2024-05-20', title: 'Shift 1' }, { resourceId: '57', start: '2024-05-21', title: 'Shift 2' } ], // This callback runs AFTER all events are rendered eventAfterAllRender: function(view) { // First, clean up any existing custom divs to avoid duplicates $('.addplusspan').remove(); // Loop through your resource event data resourceEvents.forEach(item => { // Extract the inner data object (since your data is nested under item1/item2) const eventDetails = Object.values(item)[0]; const targetResourceId = eventDetails.Resource_Id; const days = parseInt(eventDetails.Days); const hours = parseInt(eventDetails.Hours); // Calculate your positioning values const dayPosition = 100 * days; const hourPosition = 20 * hours; // Target ONLY day cells that have events AND match the resource ID $('.fc-day:has(.fc-event[data-resource-id="' + targetResourceId + '"])').each(function() { // Append the custom div to the matching day cell $(this).append(` <div class='addplusspan' style='display:block; position:absolute; left:${dayPosition}px; top:${hourPosition}px;'> + </div> `); }); }); } }); });
Step 3: Add Critical CSS
To make the absolute positioning work correctly, add this CSS to your stylesheet:
.fc-day { position: relative; /* Ensures the custom div is positioned relative to the day cell */ } .addplusspan { z-index: 10; /* Makes sure your div sits above other calendar elements */ color: white; background: #28a745; width: 20px; height: 20px; border-radius: 50%; text-align: center; line-height: 20px; font-weight: bold; }
Key Improvements Over Your Previous Attempts:
- Timing: Uses
eventAfterAllRenderto guarantee events are rendered before modifying the DOM. - Precise Targeting: Uses
:has(.fc-event)to only select days with events, and matches the resource ID to ensure the div goes to the right cells. - Cleanup: Removes old custom divs before adding new ones, preventing duplicates on calendar view changes.
- Readability: Simplifies the loop through your nested data object using
Object.values.
This should give you exactly what you need—custom divs only on dates that have events, linked to the correct resources.
内容的提问来源于stack exchange,提问作者chirag p




