Interactive Bootstrap 5 Event Calendar Plugin - jQuery bs-calendar
File Size: | 343 KB |
---|---|
Views Total: | 280 |
Last Update: | |
Publish Date: | |
Official Website: | Go to website |
License: | MIT |

bsCalendar is a simple yet robust jQuery plugin for creating responsive, customizable, full-featured event calendars styled with the latest Bootstrap 5 framework.
It handles the basics well: rendering the calendar grid, switching calendar views, basic localization, and fetching event data from a backend.
You get controls for navigation, adding events (by clicking empty areas), and interacting with existing events (click to update/remove).
Key Features:
- Bootstrap 5 based: Uses Bootstrap's grid, components, and styling for a consistent look.
- Multiple Views: Switch between day, week, month, and year displays.
- Dynamic Data Loading: Fetch appointments/events from a backend API using the
url
option. - Interactive Events: Click empty cells to add events, click existing events for potential updates/removals (requires custom handling).
- Customizable Options: Configure locale, start day of the week, colors, icons, available views, and more.
- Light/Dark Mode: Adapts to Bootstrap's color modes.
- Localization: Translate labels like 'Day', 'Week', 'Today', etc., via the
translations
option. - Search Functionality: Basic appointment search capability (if enabled).
- API Methods: Programmatically refresh, clear, update options, or destroy the calendar instance.
How to use it:
1. To get started, make sure you have jQuery library, Bootstrap framework, and Bootstrap Icons loaded in your document.
<!-- jQuery --> <script src="/path/to/cdn/jquery.min.js"></script> <!-- Bootstrap --> <link rel="stylesheet" href="/path/to/cdn/bootstrap.min.css" /> <script src="/path/to/cdn/bootstrap.bundle.min.js"></script> <!-- Bootstrap Icons --> <link rel="stylesheet" href="/path/to/cdn/bootstrap-icons.min.css">
2. Download the plugin and add the 'bs-calendar.min.js' script to the document.
<script src="/path/to/dist/bs-calendar.min.js"></script>
3. Create a container to hold the event calendar.
<div id="myCalendar"> </div>
4. Initialize bs-calendar with default options.
$(document).ready(function() { $('#myCalendar').bsCalendar({ // options here }); });
5. Add custom holidays to the calendar. It also supports for public holidays API integration. See 'openHolidays.js' in the zip for details.
$('#myCalendar').bsCalendar({ holidays: function (data) { return new Promise((resolve, reject) => { Extract the start and end years from the input const startYear = new Date(data.start).getFullYear(); const endYear = new Date(data.end).getFullYear(); const locale = getLanguageAndCountry(data.locale); const openHolidays = new OpenHolidays(); openHolidays.getPublicHolidays(locale.country, startYear + '-01-01', endYear + '-12-31', locale.language) .then(response => { console.log(response); const holidays = []; for (const holiday of response) { holidays.push({ startDate: holiday.startDate, endDate: holiday.endDate, title: holiday.name[0].text, }); } resolve(holidays); }) .catch(error => { reject(error); }); }); }, });
6. Fetch data dynamically via the url
option. When the view changes or the calendar loads initially, the internal fetchAppointments
function kicks in:
- It determines the required date range (
fromDate
,toDate
) based on the current view or theyear
for the year view. If searching, it uses thesearch
term. - It constructs a
requestData
object containing these parameters (view
,fromDate
,toDate
oryear
orsearch
). - If
queryParams
is defined, it calls that function to potentially add more data to the request (like user IDs, filters). - It makes an AJAX request (or calls your provided function) using the
url
and therequestData
. It expects a JSON response containing an array of appointment objects, includingid
,title
,start
,end
,allDay
,color
, etc. - On success, it processes the returned appointments and renders them onto the calendar grid. It positions them based on their start/end dates and times.
- Error handling is included, and
debug: true
helps trace this process.
$(document).ready(function() { $('#myCalendar').bsCalendar({ url: url }); });
// Example async function url(query) { console.log('index url', query); await sleep(Math.floor(Math.random())); return new Promise((resolve, reject) => { try { const fromDate = query.fromDate ? new Date(`${query.fromDate}T00:00:00`) : null; const toDate = query.toDate ? new Date(`${query.toDate}T23:59:59`) : null; const search = query.search; if (search && !fromDate && !toDate) { const limit = query.limit; const offset = query.offset; return resolve(getAppointmentsBySearch(search, limit, offset)); } if (query.view === 'year') { return resolve(generateDates(query.year)); } const appointments = generateRandomAppointments( (fromDate || new Date('1970-01-01T00:00:00')).toISOString(), (toDate || new Date('9999-12-31T23:59:59')).toISOString(), query.view ); const filteredAppointments = appointments.filter(appointment => { const appointmentStart = new Date(appointment.start); const appointmentEnd = new Date(appointment.end); return ( (!fromDate || appointmentStart >= fromDate) && (!toDate || appointmentEnd <= toDate) ); }); if (search) { const searchFilteredAppointments = filteredAppointments.filter(appointment => { return appointment.title.toLowerCase().includes(search.toLowerCase()); }); return resolve(searchFilteredAppointments); } resolve(filteredAppointments); } catch (error) { reject(error); } }); }
7. More configuration options:
$('#myCalendar').bsCalendar({ locale: 'en-UK', title: 'Calendar', startWeekOnSunday: true, navigateOnWheel: true, rounded: 5, // 1-5 search: { limit: 10, offset: 0 }, startDate: new Date(), startView: 'month', // day, week, month, year defaultColor: 'primary', views: ['year', 'month', 'week', 'day'], holidays: null, // an object containing 'federalState', 'country', and 'language' translations: { day: 'Day', week: 'Week', month: 'Month', year: 'Year', today: 'Today', appointment: 'Appointment', search: 'Type and press Enter', searchNoResult: 'No appointment found' }, icons: { day: 'bi bi-calendar-day', week: 'bi bi-kanban', month: 'bi bi-calendar-month', year: 'bi bi-calendar4', add: 'bi bi-plus-lg', menu: 'bi bi-list', search: 'bi bi-search', prev: 'bi bi-chevron-left', next: 'bi bi-chevron-right', link: 'bi bi-box-arrow-up-right', appointment: 'bi bi-clock', appointmentAllDay: 'bi bi-brightness-high' }, url: null, queryParams: null, topbarAddons: null, sidebarAddons: null, debug: false, formatter: { day: formatterDay, week: formatterWeek, month: formatterMonth, search: formatterSearch, holiday: formatterHoliday, window: formatInfoWindow, duration: formatDuration, }, hourSlots: { height: 30, // one hour in px start: 0, // starting hour as integer end: 24 // ending hour as integer } });
8. API methods.
// Reloads the current view data. $('#myCalendar').bsCalendar('refresh'); // Removes all displayed appointments. $('#myCalendar').bsCalendar('clear'); // Change options on the fly. $('#myCalendar').bsCalendar('updateOptions', { startView: 'week' }); // Remove the calendar instance and clean up. $('#myCalendar').bsCalendar('destroy'); // Jump to a specific date. $('#myCalendar').bsCalendar('setDate', '2025-04-11'); // Jump back to the current date. $('#myCalendar').bsCalendar('setToday');
9. Event handlers.
$('#myCalendar').on('add.bs.calendar', function (event, data) { // ... }) $('#myCalendar').on('edit.bs.calendar', function (event, appointment, extras) { // ... }) $('#myCalendar').on('view.bs.calendar', function (event, view) { // ... })
Changelog:
2025-04-17
- Removed the unused OpenHolidays.js file and adjusted the bs-calendar defaults including locale, wheel navigation, and title formatting.
2025-04-16
- Add dynamic current-time indicator and refactor slot handling
2025-04-15
- Enhance holiday settings and rendering logic.
2025-04-14
- Refactor holiday loading and improve settings structure
2025-04-12
- Add support for school holidays in calendar
This awesome jQuery plugin is developed by ThomasDev-de. For more Advanced Usages, please check the demo page or visit the official website.
- Prev: Lightweight Single & Multi-Month Picker jQuery Plugin
- Next: None