# FullCalendar.js

###### FullCalendar.js page with notes.

## Powerful Calendar Management for Modern Web Applications

FullCalendar is a full-sized, drag & drop JavaScript event calendar for modern browsers. It's designed to be a highly customizable solution for displaying and managing events, appointments, and schedules in web applications.

In SmartAdmin, FullCalendar is integrated with a custom Bootstrap theme (`fullcalendar.bootstrap.theme.js`) that ensures visual consistency with the rest of the application.

Pro Tip: SmartAdmin's FullCalendar integration uses the Smart Admin icon system and Bootstrap styling for seamless visual integration with your dashboard.

## Installation

FullCalendar needs to be added to your project. Here's how to set it up:

#### 1. Including Required Files

    // Add the scripts as modules in your HTML
    <script type="module" src="plugins/fullcalendar/index.global.min.js"></script>

    // Or import them in your JavaScript module
    import { FullCalendar } from './plugins/fullcalendar/fullcalendar.bundle.js';
    // Make sure to also include the CSS in your HTML or via a CSS loader

#### 2. Initialize a Calendar

    // After importing the modules as shown above
    document.addEventListener('DOMContentLoaded', function() {
        const calendarEl = document.getElementById('calendar');

        const calendar = new FullCalendar.Calendar(calendarEl, {
            themeSystem: 'bootstrap', // Use the SmartAdmin Bootstrap theme
            initialView: 'dayGridMonth',
            headerToolbar: {
                left: 'prev,next today',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
            },
            events: [
                {
                    title: 'Meeting',
                    start: '2023-01-10T14:30:00',
                    end: '2023-01-10T16:30:00'
                },
                {
                    title: 'Conference',
                    start: '2023-01-11',
                    end: '2023-01-13'
                }
            ]
        });

        calendar.render();
    });

#### HTML Structure

    <!-- Basic Calendar Container -->
    <div id="calendar"></div>

    <!-- Panel-Based Calendar Container (Recommended) -->
    <div id="panel-1" class="panel">
        <div class="panel-hdr">
            <h2>Calendar <span class="fw-300"><i>View</i></span></h2>
            <div class="panel-toolbar">
                <button class="btn btn-panel" data-action="panel-collapse">
                    <!-- Panel controls -->
                </button>
            </div>
        </div>
        <div class="panel-container show">
            <div class="panel-content">
                <div id="calendar"></div>
            </div>
        </div>
    </div>

Important:

- You need to include the FullCalendar files in your project - they are not automatically loaded.
- FullCalendar requires a container with a defined height. Without it, the calendar won't be visible.
- Make sure to include both the JavaScript modules and the CSS file.
- For more advanced documentation, refer to the official FullCalendar documentation.

## SmartAdmin Bootstrap Theme

SmartAdmin includes a custom Bootstrap theme for FullCalendar that ensures visual consistency with the rest of the application. The theme is defined in `fullcalendar.bootstrap.theme.js`.

    // Excerpt from the bootstrap theme definition
    class BootstrapTheme extends Theme {
        // CSS classes for various elements
        classes = {
            root: 'fc-theme-bootstrap',
            table: 'table table-calendar', // Uses Bootstrap table styling
            tableCellShaded: 'table-active',
            buttonGroup: 'btn-group',
            button: 'btn btn-outline-default btn-sm',
            buttonActive: 'active',
            popover: 'popover',
            popoverHeader: 'popover-header',
            popoverContent: 'popover-body',
        };

        // Icon definitions using SmartAdmin icon system
        baseIconClass = 'sa';
        iconClasses = {
            close: 'sa-close',
            prev: 'sa-chevron-left',
            next: 'sa-chevron-right',
            prevYear: 'sa-angle-double-left',
            nextYear: 'sa-angle-double-right',
        };
    }

Pro Tip: The SmartAdmin theme uses our custom icon system with the `sa-` prefix. This ensures all calendar controls match the rest of your application's design.

## Configuration Options

FullCalendar offers extensive configuration options. Here are some of the most common ones:

Option | Type | Description
--- | --- | ---
`initialView` | String | The initial view when the calendar loads. Options: 'dayGridMonth', 'timeGridWeek', 'timeGridDay', 'listWeek'
`headerToolbar` | Object | Configuration for the calendar's header, with sections for left, center, and right
`events` | Array/Function/String | The events to display on the calendar. Can be an array of event objects, a function, or a URL
`editable` | Boolean | Whether the events can be dragged and resized
`selectable` | Boolean | Whether dates can be selected by clicking and dragging
`businessHours` | Object/Boolean | Emphasizes certain time slots on the calendar
`nowIndicator` | Boolean | Whether to show an indicator for the current time
`weekNumbers` | Boolean | Whether to show week numbers
`height` | Number/String/Function | Sets the height of the calendar. Can be 'auto', a pixel value, or 'parent'
`themeSystem` | String | The theme system to use. In SmartAdmin, set this to 'bootstrap'

Pro Tip: When using FullCalendar with SmartAdmin, always set `themeSystem: 'bootstrap'` to use the custom Bootstrap theme integration.

## Event Handling

FullCalendar provides extensive event handling capabilities. Here's how to define and manage events:

#### Event Object Properties

    // Basic event object structure
    {
        id: '123',                      // Unique identifier
        title: 'Meeting with Client',   // Event title
        start: '2023-01-10T10:30:00',   // Start date/time (ISO8601 format)
        end: '2023-01-10T12:30:00',     // End date/time (optional)
        allDay: false,                  // Whether it's an all-day event
        url: 'https://example.com',     // Makes the event clickable as a link (optional)
        className: 'bg-success',        // CSS class names for styling (optional)
        editable: true,                 // Whether this specific event is editable (optional)
        extendedProps: {                // Additional custom data (optional)
            department: 'Marketing',
            location: 'Conference Room A'
        }
    }

#### Event Sources

    // Array of event objects
    events: [
        { title: 'Event 1', start: '2023-01-01' },
        { title: 'Event 2', start: '2023-01-05', end: '2023-01-07' }
    ]

    // JSON feed (AJAX)
    events: '/api/events'

    // Function that fetches events
    events: function(info, successCallback, failureCallback) {
        console.log('Fetching events for', info.startStr, 'to', info.endStr);

        fetch('/api/events?start=' + info.startStr + '&end=' + info.endStr)
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.json();
            })
            .then(data => {
                console.log('Loaded events:', data);
                successCallback(data);
            })
            .catch(error => {
                console.error('Error loading events:', error);
                failureCallback(error);
            });
    }

    // Multiple event sources with different colors
    eventSources: [
        {
            url: '/api/events/team-a',
            color: 'var(--success-500)',   // All events from this source will be this color
            textColor: 'white'             // Text color for this source
        },
        {
            url: '/api/events/team-b',
            color: 'var(--info-500)',
            textColor: 'white'
        }
    ]

#### Event Callbacks

    const calendar = new Calendar(calendarEl, {
        // ...other options

        // Triggered when an event is clicked
        eventClick: function(info) {
            alert('Event: ' + info.event.title);

            // Change the background color of the event
            info.event.setProp('backgroundColor', 'var(--danger-500)');

            // To prevent default action (URL navigation)
            info.jsEvent.preventDefault();
        },

        // Triggered when an event is dragged and dropped
        eventDrop: function(info) {
            if (!confirm("Are you sure you want to move this event?")) {
                info.revert(); // Revert the change
            } else {
                // Update the event in your database
                updateEventInDatabase(info.event);
            }
        },

        // Triggered when an event is resized
        eventResize: function(info) {
            alert('Event has been resized. New end time: ' + info.event.end);
        },

        // Triggered when dates are selected by clicking and dragging
        select: function(info) {
            const title = prompt('Enter a new title for your event:');
            if (title) {
                calendar.addEvent({
                    title: title,
                    start: info.startStr,
                    end: info.endStr,
                    allDay: info.allDay
                });
            }
            calendar.unselect(); // Clear selection
        }
    });

## Advanced Features

#### API Methods

    // Get a reference to the calendar
    const calendar = new Calendar(calendarEl, options);
    calendar.render();

    // Navigate to different dates
    calendar.next();     // Move to next month/week/day
    calendar.prev();     // Move to previous month/week/day
    calendar.today();    // Move to today
    calendar.gotoDate('2023-05-01'); // Jump to a specific date

    // Change views
    calendar.changeView('timeGridWeek');  // Switch to week view
    calendar.changeView('dayGridMonth');  // Switch to month view

    // Event manipulation
    const event = calendar.getEventById('123');
    if (event) {
        event.setProp('title', 'Updated Title');   // Update title
        event.setStart('2023-01-12T10:00:00');     // Update start time
        event.setEnd('2023-01-12T12:00:00');       // Update end time
        event.setAllDay(true);                     // Make it an all-day event
        event.setExtendedProp('status', 'confirmed'); // Update custom property
        event.remove();                            // Remove the event
    }

    // Add a new event
    calendar.addEvent({
        title: 'New Event',
        start: '2023-01-15'
    });

    // Programmatically select dates
    calendar.select('2023-01-24', '2023-01-26');

    // Refetch events (if using dynamic source)
    calendar.refetchEvents();

#### Localization

    // Import the locale
    import frLocale from '@fullcalendar/core/locales/fr';

    const calendar = new Calendar(calendarEl, {
        // ...other options
        locale: frLocale,   // Use French locale

        // Or use multiple locales
        locales: [frLocale, esLocale],
        locale: 'fr'        // Set the active locale
    });

#### Business Hours

    // Simple business hours (9am to 5pm, Monday to Friday)
    businessHours: true

    // Customized business hours
    businessHours: {
        daysOfWeek: [1, 2, 3, 4, 5], // Monday to Friday
        startTime: '08:00',           // 8am
        endTime: '18:00'              // 6pm
    }

    // Multiple business hour ranges
    businessHours: [
        {
            daysOfWeek: [1, 2, 3, 4], // Monday to Thursday
            startTime: '08:00',
            endTime: '18:00'
        },
        {
            daysOfWeek: [5],          // Friday
            startTime: '08:00',
            endTime: '14:00'          // 2pm (shorter day)
        }
    ]

## SmartAdmin Integration

For optimal integration with SmartAdmin, consider these tips:

#### Event Colors

Use SmartAdmin color variables for consistent styling:

    // Use SmartAdmin color variables
    events: [
        {
            title: 'Critical Task',
            start: '2023-01-05',
            backgroundColor: 'var(--danger-500)',
            borderColor: 'var(--danger-500)'
        },
        {
            title: 'Team Meeting',
            start: '2023-01-07',
            backgroundColor: 'var(--primary-500)',
            borderColor: 'var(--primary-500)'
        },
        {
            title: 'Completed Project',
            start: '2023-01-09',
            backgroundColor: 'var(--success-500)',
            borderColor: 'var(--success-500)'
        }
    ]

    // Or use predefined SmartAdmin classes
    events: [
        {
            title: 'Warning Event',
            start: '2023-01-11',
            classNames: ['bg-warning-500', 'text-white']
        },
        {
            title: 'Info Event',
            start: '2023-01-13',
            classNames: ['bg-info-500', 'text-white']
        }
    ]

#### Panel Integration

Use SmartAdmin panels for a consistent look:

    <div class="row">
        <div class="col-xl-12">
            <div id="panel-1" class="panel">
                <div class="panel-hdr">
                    <h2>
                        Company <span class="fw-300"><i>Calendar</i></span>
                    </h2>
                    <div class="panel-toolbar">
                        <button class="btn btn-panel" data-action="panel-collapse">
                            <svg class="sa-icon">
                                <use class="panel-collapsed-icon" href="img/sprite.svg#minus-circle"></use>
                                <use class="panel-expand-icon" href="img/sprite.svg#plus-circle"></use>
                            </svg>
                        </button>
                        <button class="btn btn-panel" data-action="panel-fullscreen">
                            <svg class="sa-icon">
                                <use href="img/sprite.svg#stop-circle"></use>
                            </svg>
                        </button>
                    </div>
                </div>
                <div class="panel-container show">
                    <div class="panel-content">
                        <div id="calendar"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

#### Modal Integration for Event Details

    // Calendar setup with event click handling for modals
    const calendar = new Calendar(calendarEl, {
        // ...other options
        eventClick: function(info) {
            // Prevent default action (URL navigation)
            info.jsEvent.preventDefault();

            // Get event details
            const event = info.event;
            const title = event.title;
            const start = event.start ? event.start.toLocaleString() : '';
            const end = event.end ? event.end.toLocaleString() : '';
            const description = event.extendedProps.description || '';

            // Populate and show modal with Bootstrap 5
            const modal = new bootstrap.Modal(document.getElementById('event-details-modal'));
            document.getElementById('modal-event-title').textContent = title;
            document.getElementById('modal-event-time').textContent = start + ' - ' + end;
            document.getElementById('modal-event-description').textContent = description;

            // Set up edit/delete buttons if needed
            document.getElementById('edit-event-btn').onclick = function() {
                // Open edit form for this event
                openEditForm(event);
                modal.hide();
            };

            document.getElementById('delete-event-btn').onclick = function() {
                if (confirm('Are you sure you want to delete this event?')) {
                    event.remove();
                    // Also delete from backend
                    deleteEventFromServer(event.id);
                    modal.hide();
                }
            };

            modal.show();
        }
    });

## Troubleshooting

Common Issues:

- Calendar not displaying? Ensure the container has a defined height.
- Events not appearing? Check the date range and time format of your events.
- Styling issues? Make sure `themeSystem: 'bootstrap'` is set.
- Icons not showing? Verify the custom theme is properly loaded.

#### Calendar Height Issues

    // Set explicit height
    const calendar = new Calendar(calendarEl, {
        // ...other options
        height: 800  // Explicit pixel height
    });

    // Or use parent container's height
    const calendar = new Calendar(calendarEl, {
        // ...other options
        height: 'parent'  // Use parent container's height
    });

    // Or use CSS
    #calendar {
        height: 800px;
    }

    // For responsive height
    #calendar {
        height: calc(100vh - 250px); /* Viewport height minus offset */
    }

#### AJAX Loading Issues

    // Debug AJAX event loading
    events: function(info, successCallback, failureCallback) {
        console.log('Fetching events for', info.startStr, 'to', info.endStr);

        fetch('/api/events?start=' + info.startStr + '&end=' + info.endStr)
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.json();
            })
            .then(data => {
                console.log('Loaded events:', data);
                successCallback(data);
            })
            .catch(error => {
                console.error('Error loading events:', error);
                failureCallback(error);
            });
    }

## Further Resources

For more advanced usage and detailed API documentation, refer to these resources:

- Official FullCalendar Documentation
- FullCalendar Bootstrap Theme Documentation
- FullCalendar GitHub Repository
- Available FullCalendar Plugins

##### On This Page

- Introduction
- Installation
- SmartAdmin Theme
- Configuration Options
- Event Handling
- Advanced Features
- SmartAdmin Integration
- Troubleshooting
- Further Resources

#### Hi Sunny,

how can I help you today?
Analyze my data

Create a new report

Summarize my Calendar

App Builder
Unlock limitless design potential with 16+ layout combinations and extensive customization options—tailor your dashboard to fit your exact needs.
Header position fixed
Navigation full height
Navigation position fixed
Navigation collapsed
Navigation Minified
Dark Navigation
Colorblind Mode
High Contrast Mode