Vanilla Calendar JS Library for Date Picking, Scheduling, and Timelines
1. Install the package with NPM and import modules into your project:
npm install @calendarjs/ce
import { Calendar } from '@calendarjs/ce';
import { Schedule } from '@calendarjs/ce';
import { Timeline } from '@calendarjs/ce'; 2. Or load it from a CDN:
<!-- Load the stylesheet first --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@calendarjs/ce/dist/style.min.css" /> <!-- Load LemonadeJS before CalendarJS in browser builds --> <script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@calendarjs/ce/dist/index.min.js"></script>
3. Create an inline range calendar and a time picker
<div id="report-range"></div>
<input id="publish-at" />
<script>
// Create an inline range calendar for a reporting window
const reportRange = calendarjs.Calendar(document.getElementById('report-range'), {
type: 'inline',
range: true,
grid: true,
startingDay: 1,
validRange: ['2026-04-01', '2026-05-31'],
value: ['2026-04-12', '2026-04-19'],
onchange: function(self, value) {
// Read the selected range after every change
console.log('Range value:', value);
}
});
// Bind a popup calendar to an input field
const publishAt = calendarjs.Calendar(document.getElementById('publish-at'), {
type: 'default',
input: document.getElementById('publish-at'),
time: true,
format: 'MMMM DD, YYYY HH:MI',
value: '2026-04-20 15:45:00',
onchange: function(self, value) {
// Store the picked date and time in your form state
console.log('Publish at:', value);
}
});
// Open the popup calendar from code if you need a custom trigger
publishAt.open();
</script>
4. Build a weekly schedule:
<div id="team-board"></div>
<script>
// Seed the scheduler with a few meetings
const teamBoard = calendarjs.Schedule(document.getElementById('team-board'), {
type: 'week',
value: '2026-04-20',
grid: 30,
overlap: false,
validRange: ['08:00', '19:00'],
data: [
{
guid: 'evt-101',
title: 'Design review',
date: '2026-04-21',
start: '09:00',
end: '10:30',
color: '#b86e2f'
},
{
guid: 'evt-102',
title: 'Ops sync',
date: '2026-04-22',
start: '13:00',
end: '14:00',
color: '#5e7f4a'
}
],
oncreate: function(self, events) {
// Persist new events after user edits
console.log('Created:', events);
},
onchangeevent: function(self, newValue, oldValue) {
// Track updates for autosave or audit logs
console.log('Changed:', newValue, oldValue);
},
onerror: function(self, message) {
// Show validation feedback in your UI
console.log('Schedule error:', message);
}
});
// Lock early morning and late evening blocks
teamBoard.setReadOnly([['00:00', '08:00'], ['19:00', '23:59']]);
// Add an event from code
teamBoard.addEvents({
guid: 'evt-103',
title: 'Client handoff',
date: '2026-04-23',
start: '16:00',
end: '17:00',
color: '#9f5140'
});
</script>
5. Generate a timeline:
<div id="release-timeline"></div>
<script>
// Create a project timeline with dated milestones
const releaseTimeline = calendarjs.Timeline(document.getElementById('release-timeline'), {
type: 'monthly',
align: 'left',
order: 'asc',
controls: true,
data: [
{
title: 'Spec freeze',
subtitle: 'Planning',
description: 'The team locked scope for the next release cycle.',
date: new Date('2026-04-02'),
borderColor: '#b86e2f',
borderStyle: 'solid'
},
{
title: 'QA pass',
subtitle: 'Validation',
description: 'QA finished the final regression pass.',
date: new Date('2026-04-11'),
borderColor: '#5e7f4a',
borderStyle: 'solid'
},
{
title: 'Public launch',
subtitle: 'Release',
description: 'The new build went live to all users.',
date: new Date('2026-04-18'),
borderColor: '#9f5140',
borderStyle: 'dashed'
}
],
onupdate: function(self) {
// React to monthly filtering or data changes
console.log('Timeline updated');
}
});
// Move to the next month in monthly mode
releaseTimeline.next();
releaseTimeline.updateResult();
</script>
6. Use the helper utilities:
// Read the current UTC date string
const nowValue = calendarjs.Helpers.now();
// Convert an ISO date to an Excel style serial number
const serialValue = calendarjs.Helpers.dateToNum('2026-04-20 10:00:00');
// Convert the serial number back to a date string
const restoredDate = calendarjs.Helpers.numToDate(serialValue);
// Turn a timestamp into a relative label
const relativeLabel = calendarjs.Helpers.prettify('2026-04-19 10:00:00');
console.log(nowValue, serialValue, restoredDate, relativeLabel);
type ('default' | 'auto' | 'picker' | 'inline'): Sets the calendar display mode.format (string): Sets the output format for rendered values.range (boolean): Turns range selection on or off.value (number | string): Sets the initial calendar value.numeric (boolean): Returns Excel style serial numbers in place of ISO strings.footer (boolean): Shows or hides the footer controls.time (boolean): Shows the hour and minute picker.grid (boolean): Turns grid mode on or off.placeholder (string): Sets placeholder text for bound inputs.disabled (boolean): Locks the calendar UI.startingDay (number): Sets the first weekday from 0 to 6.validRange (number[] | string[]): Restricts selectable dates to a range.data (Array<{date: string, [key: string]: any}>): Adds event data for calendar markers.wheel (boolean): Turns mouse wheel view changes on or off.input (HTMLInputElement | 'auto'): Binds the calendar to an input element.initInput (boolean): Applies input setup and calendar classes.onchange ((self: object, value: string) => void): Runs after the value changes.onupdate ((self: object, value: string) => void): Runs after the view updates.onclose ((self: object, origin: string) => void): Runs after the modal closes.onopen ((self: object) => void): Runs after the modal opens.onChange ((e: Event) => void): Exposes a React focused change hook.type ('week' | 'day' | 'weekdays'): Sets the schedule view type.weekly (boolean): Uses weekday columns in place of dated columns.value (string): Sets the initial ISO date in YYYY-MM-DD format.data (Schedule.Event[]): Loads the schedule with event records.grid (number): Sets the grid step in minutes.overlap (boolean): Permits overlapping events.validRange (string[]): Restricts visible editing hours.readOnlyRange (string[] | string[][]): Marks one or more time ranges as read only.onbeforechange ((self: Instance, state: object) => boolean | void): Runs before a grid drag or resize change.onchange ((self: Instance, state: object) => void): Runs after a grid state change.onbeforecreate ((self: Instance, events: Event | Event[], e?: MouseEvent) => boolean | void): Runs before event creation.oncreate ((self: Instance, events: Event | Event[], e?: MouseEvent) => void): Runs after event creation.ondblclick ((self: Instance, event: Event) => void): Runs on event double click.onedition ((self: Instance, event: Event) => void): Runs when editing starts.ondelete ((self: Instance, event: Event) => void): Runs after event deletion.onchangeevent ((self: Instance, newValue: Partial<Event>, oldValue: Partial<Event>) => void): Runs after event data changes.onerror ((self: Instance, message: string) => void): Runs after validation errors.type (string | null): Sets the event type label.title (string): Sets the event title.start (string): Sets the start time in HH:MM.end (string): Sets the end time in HH:MM.guests (string): Stores guest data.location (string): Stores a location label.description (string): Stores descriptive text.color (string): Sets the event color.readonly (boolean): Locks the event from editing.guid (string): Stores the unique event id.date (string): Stores the ISO date when weekly is false.weekday (number): Stores the weekday from 0 to 6 when weekly is true.data (Timeline.Item[]): Loads the timeline with item records.type ("monthly" | string): Sets the timeline mode.align ("left" | "right" | "top" | "bottom" | string): Sets item alignment.message (string): Sets the empty state message.order ('asc' | 'desc' | undefined): Sets chronological order.width (number): Sets container width.height (number): Sets container height.url (string): Sets a remote data URL.remote (boolean): Turns remote loading on.onupdate ((self: Object) => void): Runs after the visible timeline data updates.title (string): Sets the main item label.subtitle (string): Sets the secondary label.description (string): Sets the item body text.date (string | Date): Sets the item date.borderColor (string): Sets the item border color.borderStyle (string): Sets the item border style.// Create a calendar instance
const calendar = calendarjs.Calendar(document.getElementById('calendar-root'), {
type: 'inline'
});
// Open the calendar modal
calendar.open();
// Close the calendar modal
calendar.close({ origin: 'button' });
// Check modal state
calendar.isClosed();
// Switch the calendar view
calendar.setView('months');
// Move forward in the current view
calendar.next();
// Move backward in the current view
calendar.prev();
// Reset the selected value
calendar.reset();
// Read the current value
calendar.getValue();
// Write a new value
calendar.setValue('2026-04-24');
// Accept the current selection
calendar.update();
// Create a schedule instance
const schedule = calendarjs.Schedule(document.getElementById('schedule-root'), {
type: 'week'
});
// Add one event
schedule.addEvents({
guid: 'evt-201',
title: 'Roadmap sync',
date: '2026-04-24',
start: '10:00',
end: '11:00',
color: '#b86e2f'
});
// Add multiple events
schedule.addEvents([
{
guid: 'evt-202',
title: 'Editorial review',
date: '2026-04-24',
start: '12:00',
end: '13:00',
color: '#5e7f4a'
},
{
guid: 'evt-203',
title: 'Launch prep',
date: '2026-04-25',
start: '15:00',
end: '16:00',
color: '#9f5140'
}
]);
// Update an event by guid
schedule.updateEvent('evt-201', {
title: 'Roadmap sync v2',
start: '10:30'
});
// Update an event by object reference
const firstRecord = schedule.getData()[0];
schedule.updateEvent(firstRecord, {
end: '11:30'
});
// Delete by guid
schedule.deleteEvents('evt-202');
// Delete by object
schedule.deleteEvents(firstRecord);
// Delete multiple records
schedule.deleteEvents(['evt-201', 'evt-203']);
// Clear the current visual selection
schedule.resetSelection();
// Restrict editable hours
schedule.setRange(['09:00', '18:00']);
// Mark time ranges as read only
schedule.setReadOnly([['00:00', '09:00'], ['18:00', '23:59']]);
// Read all schedule data
schedule.getData();
// Replace all schedule data
schedule.setData([
{
guid: 'evt-301',
title: 'Support block',
date: '2026-04-26',
start: '11:00',
end: '12:00',
color: '#b86e2f'
}
]);
// Read the DOM node for an event
schedule.getEvent('evt-301');
// Render the schedule again
schedule.render();
// Undo the last change
schedule.undo();
// Redo the last undone change
schedule.redo();
// Move to the next period
schedule.next();
// Move to the previous period
schedule.prev();
// Create a timeline instance
const timeline = calendarjs.Timeline(document.getElementById('timeline-root'), {
type: 'monthly',
data: []
});
// Read the bound timeline data
timeline.data;
// Move to the next month in monthly mode
timeline.next();
// Move to the previous month in monthly mode
timeline.prev();
// Rebuild the visible item list
timeline.updateResult();
// Fetch remote data when remote mode is active
timeline.fetchRemote();
// Convert a value to two digits
calendarjs.Helpers.two(7);
// Validate a Date object
calendarjs.Helpers.isValidDate(new Date());
// Validate an ISO date string
calendarjs.Helpers.isValidDateFormat('2026-04-24');
// Convert a Date to a string
calendarjs.Helpers.toString(new Date(), false);
// Convert a string into an array
calendarjs.Helpers.toArray('2026-04-24 12:30:00');
// Convert an array into a string date
calendarjs.Helpers.arrayToStringDate([2026, 4, 24, 12, 30, 0]);
// Convert a Date or string to an Excel style serial
calendarjs.Helpers.dateToNum('2026-04-24 12:30:00');
// Convert an Excel style serial back to a string
calendarjs.Helpers.numToDate(46136.520833333336);
// Convert an Excel style serial to an array
calendarjs.Helpers.numToDate(46136.520833333336, true);
// Convert a timestamp into a relative label
calendarjs.Helpers.prettify('2026-04-23 12:30:00');
// Update every .prettydate node on the page
calendarjs.Helpers.prettifyAll();
// Read the current date string
calendarjs.Helpers.now();
// Read localized weekday names
calendarjs.Helpers.weekdays;
// Read localized short weekday names
calendarjs.Helpers.weekdaysShort;
// Read localized month names
calendarjs.Helpers.months;
// Read localized short month names
calendarjs.Helpers.monthsShort;
// Set custom labels
calendarjs.setDictionary({
Reset: 'Clear',
Done: 'Apply'
});
// Read package metadata
calendarjs.about();
// Run after a calendar value changes
calendarjs.Calendar(document.getElementById('calendar-a'), {
onchange: function(self, value) {
console.log('Calendar change:', value);
}
});
// Run after the calendar view updates
calendarjs.Calendar(document.getElementById('calendar-b'), {
onupdate: function(self, value) {
console.log('Calendar update:', value);
}
});
// Run after the calendar modal closes
calendarjs.Calendar(document.getElementById('calendar-c'), {
onclose: function(self, origin) {
console.log('Calendar closed from:', origin);
}
});
// Run after the calendar modal opens
calendarjs.Calendar(document.getElementById('calendar-d'), {
onopen: function(self) {
console.log('Calendar opened');
}
});
// React focused change callback
calendarjs.Calendar(document.getElementById('calendar-e'), {
onChange: function(e) {
console.log('React style change event:', e);
}
});
// Run before a schedule drag or resize change
calendarjs.Schedule(document.getElementById('schedule-a'), {
onbeforechange: function(self, state) {
console.log('Before grid change:', state);
return true;
}
});
// Run after a schedule grid change
calendarjs.Schedule(document.getElementById('schedule-b'), {
onchange: function(self, state) {
console.log('Grid changed:', state);
}
});
// Run before creating events
calendarjs.Schedule(document.getElementById('schedule-c'), {
onbeforecreate: function(self, events, e) {
console.log('Before create:', events, e);
return true;
}
});
// Run after creating events
calendarjs.Schedule(document.getElementById('schedule-d'), {
oncreate: function(self, events, e) {
console.log('Created:', events, e);
}
});
// Run on event double click
calendarjs.Schedule(document.getElementById('schedule-e'), {
ondblclick: function(self, event) {
console.log('Double click:', event);
}
});
// Run when event editing starts
calendarjs.Schedule(document.getElementById('schedule-f'), {
onedition: function(self, event) {
console.log('Editing:', event);
}
});
// Run after deleting an event
calendarjs.Schedule(document.getElementById('schedule-g'), {
ondelete: function(self, event) {
console.log('Deleted:', event);
}
});
// Run after event data changes
calendarjs.Schedule(document.getElementById('schedule-h'), {
onchangeevent: function(self, newValue, oldValue) {
console.log('Event changed:', newValue, oldValue);
}
});
// Run after schedule validation errors
calendarjs.Schedule(document.getElementById('schedule-i'), {
onerror: function(self, message) {
console.log('Schedule error:', message);
}
});
// Run after timeline data updates
calendarjs.Timeline(document.getElementById('timeline-a'), {
onupdate: function(self) {
console.log('Timeline updated:', self);
}
});
The post Vanilla Calendar JS Library for Date Picking, Scheduling, and Timelines appeared first on CSS Script.
Neiki Editor is a vanilla JavaScript rich text editor that turns a textarea into a…
LANSING, MI (WOWO) A Michigan township official is urging communities to update zoning policies as…
A critical vulnerability in Flowise and multiple AI frameworks has been discovered by OX Security,…
Vercel has disclosed a significant security incident after threat actors gained unauthorized access to internal…
HAMMOND, IND. (WOWO) Indiana officials have approved a lease amendment that will allow more frequent…
HAMMOND, IND. (WOWO) Indiana officials have approved a lease amendment that will allow more frequent…
This website uses cookies.