Now.js Framework Documentation
CalendarManager
CalendarManager
Overview
CalendarManager is the calendar component in Now.js Framework. It supports multiple view modes: month, week, day, and timeline with events management.
When to use:
- Need to display a calendar
- Need to manage events/appointments
- Need a scheduling interface
- Need a date picker with various views
Why use it:
- ✅ Multiple views (month, week, day, timeline)
- ✅ Events support with colors
- ✅ Navigation (prev, next, today)
- ✅ Localization support
- ✅ Click callbacks (date, event)
- ✅ Configurable first day of week
- ✅ Modern UI
Basic Usage
HTML Declarative
<!-- Simple calendar -->
<div data-calendar></div>
<!-- Calendar with options -->
<div data-calendar
data-view="month"
data-locale="en"
data-first-day="1">
</div>
<!-- Calendar with events -->
<div id="my-calendar" data-calendar></div>
<script>
CalendarManager.addEvent('#my-calendar', {
id: 1,
title: 'Meeting',
start: '2024-01-15',
end: '2024-01-15',
color: '#3b82f6'
});
</script>JavaScript API
// Initialize calendar
const calendar = CalendarManager.create(
document.querySelector('#calendar'),
{
view: 'month',
locale: 'en-US',
firstDayOfWeek: 0, // Sunday
showWeekNumbers: true,
events: [
{
id: 1,
title: 'Team Meeting',
start: '2024-01-15T10:00',
end: '2024-01-15T11:00',
color: '#3b82f6'
},
{
id: 2,
title: 'Project Deadline',
start: '2024-01-20',
end: '2024-01-20',
color: '#ef4444'
}
]
}
);View Modes
Month View (default)
<div data-calendar data-view="month"></div>Displays standard monthly calendar view:
- Days in current month
- Days from previous/next month (dimmed)
- Highlight today
Week View
<div data-calendar data-view="week"></div>Displays 7 days with time slots:
- Hours displayed vertically
- Events positioned by time
- Navigate by week
Day View
<div data-calendar data-view="day"></div>Displays single day with time slots:
- Full hourly detail
- Events shown by time range
- Ideal for scheduling
Timeline View
<div data-calendar data-view="timeline"></div>Displays continuous timeline:
- Multiple days horizontally
- Events as bars
- Overview of week/month
Events
Event Structure
const event = {
id: 1, // Unique ID
title: 'Meeting', // Display title
start: '2024-01-15T10:00', // Start date/time
end: '2024-01-15T11:30', // End date/time
color: '#3b82f6', // Badge color
description: 'Team sync', // Optional description
allDay: false, // All day event
data: { /* custom data */ } // Custom data
};Add Events
// Add single event
CalendarManager.addEvent('#calendar', {
id: 1,
title: 'New Event',
start: '2024-01-15',
color: '#10b981'
});
// Add multiple events during creation
CalendarManager.create(element, {
events: [
{ id: 1, title: 'Event 1', start: '2024-01-10' },
{ id: 2, title: 'Event 2', start: '2024-01-15' }
]
});Remove Events
// Remove by ID
CalendarManager.removeEvent('#calendar', 1);Callbacks
onDateClick
Called when a date is clicked:
CalendarManager.create(element, {
callbacks: {
onDateClick: (date, event) => {
console.log('Clicked date:', date);
// Show create event form
showCreateEventModal(date);
}
}
});onEventClick
Called when an event is clicked:
CalendarManager.create(element, {
callbacks: {
onEventClick: (eventData, clickEvent) => {
console.log('Clicked event:', eventData);
// Show event details
showEventDetails(eventData);
}
}
});onViewChange
Called when view changes:
CalendarManager.create(element, {
callbacks: {
onViewChange: (view) => {
console.log('View changed to:', view);
}
}
});onDateChange
Called when navigating to a different date:
CalendarManager.create(element, {
callbacks: {
onDateChange: (date) => {
console.log('Navigated to:', date);
// Load events for new period
loadEventsForPeriod(date);
}
}
});Configuration
CalendarManager.create(element, {
// View settings
view: 'month', // 'month', 'week', 'day', 'timeline'
firstDayOfWeek: 0, // 0 = Sunday, 1 = Monday
showWeekNumbers: false, // Show week numbers
// Localization
locale: 'en-US', // Date locale
// Events
events: [], // Initial events
// Callbacks
callbacks: {
onDateClick: null,
onEventClick: null,
onViewChange: null,
onDateChange: null
}
});API Reference
CalendarManager.create(element, options)
Create a calendar
| Parameter | Type | Description |
|---|---|---|
element |
HTMLElement | Container element |
options |
object | Configuration options |
Returns: Object - Calendar instance
CalendarManager.addEvent(elementOrInstance, event)
Add an event
| Parameter | Type | Description |
|---|---|---|
elementOrInstance |
HTMLElement/string/Object | Calendar element, selector, or instance |
event |
object | Event object |
CalendarManager.addEvent('#calendar', {
id: 1,
title: 'Meeting',
start: '2024-01-15',
color: '#3b82f6'
});CalendarManager.removeEvent(elementOrInstance, eventId)
Remove an event
| Parameter | Type | Description |
|---|---|---|
elementOrInstance |
HTMLElement/string/Object | Calendar element, selector, or instance |
eventId |
any | Event ID to remove |
CalendarManager.getInstance(element)
Get calendar instance
| Parameter | Type | Description |
|---|---|---|
element |
HTMLElement | Calendar element |
Returns: Object|null - Calendar instance
CalendarManager.destroy(instance)
Destroy calendar
| Parameter | Type | Description |
|---|---|---|
instance |
Object | Calendar instance |
Instance Methods
const instance = CalendarManager.getInstance(element);
// Navigate
CalendarManager.navigate(instance, 'prev'); // Previous month/week/day
CalendarManager.navigate(instance, 'next'); // Next month/week/day
CalendarManager.goToToday(instance); // Go to today
// Change view
CalendarManager.changeView(instance, 'week');
// Re-render
CalendarManager.render(instance);Events Emitted
| Event | When Triggered | Detail |
|---|---|---|
calendar:dateClick |
Date clicked | {date, originalEvent} |
calendar:eventClick |
Event clicked | {event, originalEvent} |
calendar:viewChange |
View changed | {view} |
calendar:dateChange |
Navigated | {date} |
// Listen via EventManager
EventManager.on('calendar:dateClick', (data) => {
console.log('Date clicked:', data.date);
});Real-World Examples
Booking Calendar
<div id="booking-calendar" data-calendar data-view="week"></div>
<script>
CalendarManager.create(document.querySelector('#booking-calendar'), {
view: 'week',
locale: 'en-US',
firstDayOfWeek: 1,
callbacks: {
onDateClick: async (date) => {
const timeSlot = await showTimeSlotPicker(date);
if (timeSlot) {
await createBooking(date, timeSlot);
refreshCalendar();
}
},
onEventClick: (event) => {
showBookingDetails(event.data);
}
}
});
// Load existing bookings
async function loadBookings() {
const bookings = await ApiService.get('/api/bookings');
bookings.forEach(booking => {
CalendarManager.addEvent('#booking-calendar', {
id: booking.id,
title: booking.customer_name,
start: booking.start_time,
end: booking.end_time,
color: booking.status === 'confirmed' ? '#10b981' : '#f59e0b',
data: booking
});
});
}
loadBookings();
</script>Event Calendar with Load on Navigate
let currentEvents = [];
CalendarManager.create(element, {
view: 'month',
callbacks: {
onDateChange: async (date) => {
// Clear old events
currentEvents.forEach(e => {
CalendarManager.removeEvent(element, e.id);
});
// Load events for new month
const year = date.getFullYear();
const month = date.getMonth() + 1;
currentEvents = await ApiService.get(`/api/events?year=${year}&month=${month}`);
// Add new events
currentEvents.forEach(event => {
CalendarManager.addEvent(element, event);
});
}
}
});CSS Styling
/* Calendar container */
.calendar {
font-family: system-ui, -apple-system, sans-serif;
border: 1px solid #e5e7eb;
border-radius: 8px;
overflow: hidden;
}
/* Header */
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background: #f9fafb;
border-bottom: 1px solid #e5e7eb;
}
/* Day headers */
.calendar-day-header {
font-weight: 600;
text-align: center;
padding: 8px;
color: #6b7280;
}
/* Day cells */
.calendar-day {
min-height: 100px;
padding: 8px;
border: 1px solid #e5e7eb;
cursor: pointer;
transition: background 0.2s;
}
.calendar-day:hover {
background: #f3f4f6;
}
.calendar-day.today {
background: #eff6ff;
}
.calendar-day.other-month {
color: #9ca3af;
background: #fafafa;
}
/* Events */
.calendar-event {
padding: 2px 6px;
margin: 2px 0;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
}Common Pitfalls
⚠️ 1. Event IDs Must Be Unique
// ❌ Duplicate IDs cause problems
CalendarManager.addEvent('#cal', { id: 1, title: 'Event A' });
CalendarManager.addEvent('#cal', { id: 1, title: 'Event B' }); // Conflict!
// ✅ Use unique IDs
CalendarManager.addEvent('#cal', { id: 'evt-001', title: 'Event A' });
CalendarManager.addEvent('#cal', { id: 'evt-002', title: 'Event B' });⚠️ 2. Date Format
// ❌ Incorrect format
{ start: '15/01/2024' } // ✗
// ✅ Use ISO format
{ start: '2024-01-15' } // Date only
{ start: '2024-01-15T10:00' } // Date and timeRelated Documentation
- DateElementFactory - Date inputs
- EventManager - Events
- EventCalendar - Alternative calendar