Now.js Framework Documentation

Now.js Framework Documentation

CalendarManager

EN 15 Dec 2025 06:24

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 time