Now.js Framework Documentation

Now.js Framework Documentation

EventCalendar

EN 09 Dec 2025 15:55

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);
// Go to today
EventCalendar.goToToday(calendar);

// Change view
EventCalendar.changeView(calendar, 'week');

// Navigate
EventCalendar.navigate(calendar, 1);   // next
EventCalendar.navigate(calendar, -1);  // prev

Destroy

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