Now.js Framework Documentation
EventCalendar
EventCalendar
EventCalendar is an advanced calendar component for displaying events with support for multi-day/week/month spanning events like Google Calendar, with responsive design for mobile.
Features
- 📅 Spanning Events - Display long events as continuous bars across days/weeks/months
- 📊 3 Views - Month, Week, and Day views
- 📱 Mobile Friendly - Tap to open day detail modal
- 🔗 API Integration - Load events from API endpoint
- 🔄 ResponseHandler - Event clicks can be processed through ResponseHandler
- 🌐 i18n - Supports Thai/English
- 🌓 Dark Mode - Automatic dark mode support
Installation
CSS
<link rel="stylesheet" href="css/event-calendar.css">JavaScript
<script src="Now/js/EventCalendar.js"></script>Basic Usage
1. HTML Declarative
<!-- Basic calendar -->
<div data-event-calendar
data-view="month"
data-locale="en">
</div>
<!-- Load events from API -->
<div data-event-calendar
data-api="/api/events.php"
data-view="month"
data-locale="en"
data-views="month,week,day"
data-show-view-switcher="true">
</div>2. JavaScript API
// Create instance
const calendar = EventCalendar.create('#my-calendar', {
defaultView: 'month',
locale: 'en',
onDateClick: (date, instance) => {
console.log('Clicked:', date);
},
onEventClick: (event, instance) => {
console.log('Event:', event);
}
});
// Add events
EventCalendar.setEvents(calendar, [
{
id: 'evt-1',
title: 'Team Meeting',
start: '2025-12-09T09:00:00',
end: '2025-12-09T11:00:00',
color: '#4285F4'
},
{
id: 'evt-2',
title: 'Vacation',
start: '2025-12-20',
end: '2025-12-27',
color: '#4CAF50',
allDay: true
}
]);Data Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-event-calendar |
- | - | Mark as EventCalendar (required) |
data-view |
string | 'month' |
Default view: 'month', 'week', 'day' |
data-views |
string | 'month,week,day' |
Enabled views |
data-locale |
string | 'auto' |
Language: 'th', 'en', 'auto' |
data-first-day |
number | 0 |
First day of week (0=Sunday) |
data-max-events |
number | 3 |
Max events per day |
data-api |
string | - | URL for loading events |
data-api-method |
string | 'GET' |
HTTP method |
data-event-data-path |
string | 'data' |
Path to events in response |
data-show-navigation |
boolean | true |
Show navigation buttons |
data-show-today |
boolean | true |
Show Today button |
data-show-view-switcher |
boolean | true |
Show view switcher |
Event Data Format
{
"id": "evt-001",
"title": "Team Meeting",
"start": "2025-12-09T09:00:00",
"end": "2025-12-09T11:00:00",
"allDay": false,
"color": "#4285F4",
"description": "Weekly sync",
"location": "Conference Room A"
}| Field | Type | Required | Description |
|---|---|---|---|
id |
string | No | Event ID |
title |
string | Yes | Event title |
start |
string/Date | Yes | Start date/time |
end |
string/Date | No | End date/time |
allDay |
boolean | No | All-day event (default: true) |
color |
string | No | Event color (hex) |
API Response Format
{
"success": true,
"data": [
{
"id": "evt-001",
"title": "Holiday Trip",
"start": "2025-12-20",
"end": "2025-12-27",
"allDay": true,
"color": "#4CAF50"
}
]
}JavaScript API Methods
Managing Events
// Add event
EventCalendar.addEvent(calendar, {
title: 'New Event',
start: new Date(),
end: new Date(Date.now() + 86400000),
color: '#E91E63'
});
// Remove event
EventCalendar.removeEvent(calendar, 'event-id');
// Update event
EventCalendar.updateEvent(calendar, 'event-id', { title: 'Updated' });
// Set all events
EventCalendar.setEvents(calendar, eventsArray);
// Get events
const events = EventCalendar.getEvents(calendar);
// Refresh from API
EventCalendar.refreshEvents(calendar);Navigation
// Go to today
EventCalendar.goToToday(calendar);
// Change view
EventCalendar.changeView(calendar, 'week');
// Navigate
EventCalendar.navigate(calendar, 1); // next
EventCalendar.navigate(calendar, -1); // prevDestroy
EventCalendar.destroy(calendar);Custom Events
// Date click
document.addEventListener('eventcalendar:dateClick', (e) => {
console.log('Date:', e.detail.date);
});
// Event click
document.addEventListener('eventcalendar:eventClick', (e) => {
console.log('Event:', e.detail.event);
});
// Navigate
document.addEventListener('eventcalendar:navigate', (e) => {
console.log('Date:', e.detail.date);
});
// View change
document.addEventListener('eventcalendar:viewChange', (e) => {
console.log('View:', e.detail.view);
});ResponseHandler Integration
Event clicks can call an API and process through ResponseHandler:
<div data-event-calendar
data-api="/api/events.php"
data-on-event-click-api="/api/events/{id}">
</div>Example API Response:
{
"success": true,
"actions": [
{
"type": "modal-show",
"template": "event-detail",
"data": { "id": "evt-001", "title": "Team Meeting" }
}
]
}Spanning Events Algorithm
EventCalendar splits long events into weekly segments:
Week: Dec 1-7
┌───┬───┬───┬───┬───┬───┬───┐
│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
│░░░░░░░░░░░ Event A ░░░░░░▸│ ← continues →
│ │▓▓▓▓▓ B ▓▓▓│ │ │ │
│ │ │ │ C │+2 │ │ │ ← overflow
└───┴───┴───┴───┴───┴───┴───┘CSS Customization
:root {
--ec-primary: #E91E63;
--ec-today-bg: #fce4ec;
--ec-event-height: 24px;
--ec-day-height: 150px;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
:root {
--ec-bg: #1e1e1e;
--ec-text: #e8eaed;
}
}Example
See live example at: /examples/event-calendar/index.html
Related
- CalendarManager - Basic calendar
- Modal - Modal component
- ResponseHandler - API response handler