innocore-scheduler
v1.0.3
Published
Config-driven, data-source agnostic scheduler/calendar component built with pure HTML, CSS, and JavaScript
Maintainers
Readme
@innocore/scheduler
A config-driven, data-source agnostic scheduler/calendar component built with pure HTML, CSS, and JavaScript.
Features
- 📅 Multiple Views: Day, Week, Month, and Agenda views
- 🔧 Fully Configurable: Event fields, views, and behaviors are all configurable
- 🌐 Timezone Support: Built-in timezone conversion and display
- 🔁 Recurring Events: Support for daily, weekly, and monthly recurring events
- 📱 Responsive: Works seamlessly across desktop and mobile devices
- 🎨 Customizable: Easy to style and extend
- 🔄 Two-Way Data Binding: Automatic synchronization between UI and data
Installation
npm install @innocore/schedulerBasic Usage
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="node_modules/@innocore/scheduler/dist/scheduler.css">
</head>
<body>
<div id="scheduler-container"></div>
<script src="node_modules/@innocore/scheduler/dist/scheduler.min.js"></script>
<script>
const scheduler = new Scheduler.default({
container: '#scheduler-container',
view: 'week',
startHour: 8,
endHour: 18,
events: [
{
id: '1',
title: 'Team Meeting',
startDate: '2026-01-22T10:00:00',
endDate: '2026-01-22T11:00:00',
location: 'Conference Room A'
}
]
});
scheduler.render();
</script>
</body>
</html>Configuration
Core Configuration
const scheduler = new Scheduler.default({
container: '#scheduler-container', // Container selector or element
view: 'week', // Initial view: 'day', 'week', 'month', 'agenda'
currentDate: new Date(), // Initial date
startHour: 8, // Start hour for day/week views
endHour: 18, // End hour for day/week views
hourHeight: 60, // Height per hour in pixels
timezone: 'local', // Display timezone
slotClickEnabled: true, // Enable click to create events
events: [] // Initial events array
});UI Configurability
The scheduler provides complete control over which UI elements and interactions are available:
Configurable Views
Control which calendar views are available to users:
const scheduler = new Scheduler.default({
container: '#scheduler-container',
// Only show Week and Month views (hide Day and Agenda)
enabledViews: ['week', 'month']
// Or only show a single view
// enabledViews: ['week']
// Default: ['day', 'week', 'month', 'agenda']
});Valid view names: 'day', 'week', 'month', 'agenda'
Read-Only Mode
Make the scheduler completely read-only (no editing or creating):
const scheduler = new Scheduler.default({
container: '#scheduler-container',
// Enable read-only mode
readOnly: true
// Default: false
});When readOnly: true:
- All event creation buttons are hidden
- Clicking on time slots does nothing
- Clicking on events does not open edit modal
- Event tooltips show information but no Edit/Delete buttons
- Perfect for displaying schedules that should not be modified
Timezone Selector Visibility
Control whether the timezone dropdown is visible:
const scheduler = new Scheduler.default({
container: '#scheduler-container',
// Hide the timezone selector
showTimezoneSelector: false
// Default: true
});Export Buttons Configuration
Control which export format buttons are available in the toolbar:
const scheduler = new Scheduler.default({
container: '#scheduler-container',
// Option 1: Show all export formats
showExportButtons: true
// Option 2: Show specific formats only
showExportButtons: ['json', 'csv'] // Only JSON and CSV
// Option 3: Show no export buttons (default)
showExportButtons: false
});Available export formats: 'json', 'csv', 'excel', 'ical'
Examples:
// Only JSON and CSV exports
showExportButtons: ['json', 'csv']
// Only Excel export
showExportButtons: ['excel']
// All formats
showExportButtons: true // or ['json', 'csv', 'excel', 'ical']
// No export buttons
showExportButtons: falseConfiguration Examples
Example 1: Read-Only Schedule Display
const scheduler = new Scheduler.default({
container: '#scheduler-container',
enabledViews: ['week'], // Only week view
readOnly: true, // No editing or creating
showTimezoneSelector: false, // Hide timezone dropdown
eventSources: [fetchScheduleData()] // Load events from API
});Example 2: Minimal Configuration
const scheduler = new Scheduler.default({
container: '#scheduler-container',
enabledViews: ['month'], // Month view only
showTimezoneSelector: false // Hide timezone selector
});Example 3: Full Featured with Custom Fields
const scheduler = new Scheduler.default({
container: '#scheduler-container',
enabledViews: ['day', 'week', 'month'],
showTimezoneSelector: true, // Show timezone selector
eventFormFields: customFields // Custom event fields
});Configurable Event Fields
One of the key features of @innocore/scheduler is fully configurable event fields. Event fields are not hardcoded - they are defined through configuration.
Field Configuration Structure
Each field configuration object supports the following properties:
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| key | String | Yes | Data key for the field (maps to data source) |
| label | String | Yes | Display label in the form |
| control | String | Yes | Input control type (see below) |
| dataType | String | No | Expected data type (for validation) |
| required | Boolean | No | Whether field is mandatory |
| placeholder | String | No | Placeholder text for input |
| default | Any | No | Default value if not provided |
| options | Array | No | Options for select/dropdown controls |
| min | Number/String | No | Minimum value (for number/date inputs) |
| max | Number/String | No | Maximum value (for number/date inputs) |
| pattern | String | No | Regex pattern for validation |
| rows | Number | No | Number of rows (for textarea) |
Supported Control Types
text- Single-line text inputtextarea- Multi-line text inputdate- Date pickertime- Time pickerdatetime-local- Date and time pickernumber- Number inputemail- Email inputtel- Telephone inputurl- URL inputcheckbox- Checkboxselect- Dropdown select
Default Event Fields
If not specified, the scheduler uses these default fields:
[
{
key: 'title',
label: 'Event Title',
control: 'text',
required: true,
placeholder: 'Enter event title'
},
{
key: 'startDate',
label: 'Start Date & Time',
control: 'datetime-local',
required: true
},
{
key: 'endDate',
label: 'End Date & Time',
control: 'datetime-local',
required: true
},
{
key: 'location',
label: 'Location',
control: 'text',
placeholder: 'Add location'
},
{
key: 'description',
label: 'Description',
control: 'textarea',
placeholder: 'Add description',
rows: 3
}
]Custom Event Fields Example
You can completely customize the event fields:
const scheduler = new Scheduler.default({
container: '#scheduler-container',
eventFormFields: [
{
key: 'title',
label: 'Meeting Title',
control: 'text',
required: true,
placeholder: 'Enter meeting title',
maxLength: 100
},
{
key: 'organizer',
label: 'Organizer',
control: 'text',
required: true,
placeholder: 'Enter organizer name'
},
{
key: 'startDate',
label: 'Start Time',
control: 'datetime-local',
required: true
},
{
key: 'endDate',
label: 'End Time',
control: 'datetime-local',
required: true
},
{
key: 'meetingType',
label: 'Meeting Type',
control: 'select',
required: true,
options: [
{ value: 'internal', label: 'Internal Meeting' },
{ value: 'client', label: 'Client Meeting' },
{ value: 'review', label: 'Review Meeting' }
]
},
{
key: 'location',
label: 'Location',
control: 'text',
placeholder: 'Conference room or online link'
},
{
key: 'attendees',
label: 'Number of Attendees',
control: 'number',
min: 1,
max: 100,
default: 1
},
{
key: 'isVirtual',
label: 'Virtual Meeting',
control: 'checkbox'
},
{
key: 'notes',
label: 'Meeting Notes',
control: 'textarea',
rows: 4,
placeholder: 'Add meeting notes or agenda'
},
{
key: 'priority',
label: 'Priority',
control: 'select',
options: ['Low', 'Medium', 'High', 'Urgent']
}
]
});Two-Way Data Binding
The scheduler automatically maintains two-way data binding:
UI → Data: When users create or edit events through the form, the data is automatically updated.
Data → UI: When you update events programmatically, the UI automatically reflects the changes.
// Programmatic updates automatically reflect in UI
scheduler.addEvent({
id: '123',
title: 'New Event',
startDate: '2026-01-23T14:00:00',
endDate: '2026-01-23T15:00:00',
organizer: 'John Doe',
meetingType: 'client'
});
// Get current events (with all custom fields)
const events = scheduler.getEvents();
// Update event
scheduler.updateEvent('123', {
title: 'Updated Event',
priority: 'High'
});
// Delete event
scheduler.deleteEvent('123');Data Source Mapping
Your event data can come from any source (REST API, GraphQL, Database, etc.) as long as it maps to the configured fields:
// Example: Fetch from API and map to scheduler
fetch('/api/meetings')
.then(response => response.json())
.then(apiData => {
const events = apiData.map(meeting => ({
id: meeting.meetingId,
title: meeting.subject,
startDate: meeting.startTime,
endDate: meeting.endTime,
organizer: meeting.createdBy,
location: meeting.roomName,
meetingType: meeting.type,
isVirtual: meeting.hasOnlineLink
}));
scheduler.config.events = events;
scheduler.refresh();
});Recurring Events
The scheduler supports recurring events with configurable patterns:
{
id: '1',
title: 'Daily Standup',
startDate: '2026-01-22T09:00:00',
endDate: '2026-01-22T09:15:00',
isRecurring: true,
recurrenceRule: 'FREQ=DAILY;INTERVAL=1;UNTIL=20260228T000000Z'
}Recurrence patterns supported:
- Daily:
FREQ=DAILY;INTERVAL=1 - Weekly:
FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR - Monthly:
FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15
Timezone Support
The scheduler includes built-in timezone conversion:
const scheduler = new Scheduler.default({
container: '#scheduler-container',
timezone: 'America/New_York', // Display in ET
events: [
{
id: '1',
title: 'Team Meeting',
startDate: '2026-01-22T10:00:00Z', // UTC time
endDate: '2026-01-22T11:00:00Z' // Displays as 5:00 AM ET
}
]
});Available timezones:
local- User's local timezoneUTC- Coordinated Universal TimeAmerica/New_York- Eastern TimeAmerica/Chicago- Central TimeAmerica/Denver- Mountain TimeAmerica/Los_Angeles- Pacific TimeEurope/London- GMT/BSTEurope/Paris- Central European TimeAsia/Tokyo- Japan Standard TimeAsia/Kolkata- India Standard Time
API Methods
Events Management
// Add event
scheduler.addEvent(eventData);
// Update event
scheduler.updateEvent(eventId, updatedData);
// Delete event
scheduler.deleteEvent(eventId);
// Get all events
const events = scheduler.getEvents();
// Get events in date range
const events = scheduler.getEventsInRange(startDate, endDate);View Management
// Change view
scheduler.changeView('month');
// Navigate to specific date
scheduler.goToDate(new Date('2026-02-01'));
// Refresh display
scheduler.refresh();Import/Export
// Export to iCalendar format
const icalData = scheduler.exportToICal();
// Import from iCalendar
scheduler.importFromICal(icalString);
// Export to JSON
const jsonData = JSON.stringify(scheduler.getEvents());Event Callbacks
const scheduler = new Scheduler.default({
container: '#scheduler-container',
// Called when an event is created
onEventCreate: (event) => {
console.log('Event created:', event);
},
// Called when an event is updated
onEventUpdate: (eventId, updatedData) => {
console.log('Event updated:', eventId, updatedData);
},
// Called when an event is deleted
onEventDelete: (eventId) => {
console.log('Event deleted:', eventId);
},
// Called when view changes
onViewChange: (view) => {
console.log('View changed to:', view);
},
// Called when date changes
onDateChange: (date) => {
console.log('Date changed to:', date);
},
// Called when a time slot is clicked
onSlotClick: (slotInfo) => {
console.log('Slot clicked:', slotInfo);
}
});Styling
The scheduler uses CSS custom properties for easy theming:
:root {
--sch-color-calendar: #4f46e5;
--sch-color-event-normal: #716ae9;
--sch-color-event-recurring: #c43081;
--sch-color-bg-main: #fff;
--sch-color-border: #e5e7eb;
--sch-color-text: #111827;
}Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
License
ISC
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
