Date Picker

Date Picker

Select a date, a range, or several dates from a calendar.

Add datepicker to a text input. AutoInit() starts every .datepicker except those marked no-autoinit.

The calendar is inline, not a modal. With the default options the calendar is hidden (openByDefault: false) and clicking the input does not reveal it. Pass openByDefault: true to show the calendar under the field.

<div class="field">
  <input type="text" class="date-picker" id="birthdate">
  <label for="birthdate">Birthdate</label>
</div>
Expressive.Datepicker.init(document.querySelectorAll('.datepicker'), {
  openByDefault: true
});

Wrap the input in its own .field (or another small parent). The calendar is inserted after that parent, not after the input itself.

Initialization

The IIFE bundle exposes Expressive.Datepicker. Call init yourself when you need options other than the defaults, or let Expressive.AutoInit() start every .datepicker. AutoInit uses the defaults, so the calendar stays hidden until you pass openByDefault (or a working displayPlugin pair, below).

document.addEventListener('DOMContentLoaded', function() {
  const elems = document.querySelectorAll('.datepicker');
  const instances = Expressive.Datepicker.init(elems, {
    openByDefault: true
  });
});

Per-instance options can also be passed through AutoInit:

Expressive.AutoInit(document.body, {
  Datepicker: { openByDefault: true }
});

Display

The calendar is a .datepicker-container in the page. There is no overlay and no autoClose option.

Always visible

openByDefault: true leaves the calendar in the layout. That is the reliable way to show it.

Docked popover

displayPlugin: 'docked' wraps the calendar in a .display-docked popover that appears when the input is clicked or focused with Enter, and hides when you click outside. The plugin only animates the wrapper. If openByDefault is still false, the calendar inside stays display: none. Use both:

Expressive.Datepicker.init(elem, {
  displayPlugin: 'docked',
  openByDefault: true
});

The popover is positioned in document coordinates and then appended to the input’s parent. A position: relative parent — including .field — shifts that position, so the calendar will not sit next to the field. Prefer a static wrapper if you use docked, or keep the calendar inline with openByDefault.

Optional displayPluginOptions: margin (default 5), transition (10), duration (250), and align ('left').

container renders the calendar into a specific element and does not hide it. Use a selector or a DOM node.

Options

Name Type Default Description
format String or Function 'mmm dd, yyyy' Output written to the input, or a function that takes a Date and returns a string.
parse Function null Turn the current input string back into a Date. Receives (value, format).
isDateRange Boolean false Select a start date and an end date.
dateRangeEndEl String null Selector for an existing end-date input. If omitted, a second input is created.
isMultipleSelection Boolean false Toggle several dates. Extra inputs are created as dates are added.
defaultDate Date null Initial date to view. Falls back to the input’s current value, then today.
defaultEndDate Date null Initial end date when isDateRange is true.
setDefaultDate Boolean false If true, defaultDate is also the selected value.
setDefaultEndDate Boolean false If true, defaultEndDate is also the selected end value.
disableWeekends Boolean false Prevent selecting Saturday and Sunday.
disableDayFn Function null Return true to disable that day. Receives a Date.
firstDay Number 0 First day of the week. 0 is Sunday, 1 is Monday.
minDate Date null Earliest selectable date.
maxDate Date null Latest selectable date.
yearRange Number or Array 10 Years on either side of the viewed year, or [minYear, maxYear].
yearRangeReverse Boolean false Sort the year list in reverse order.
isRTL Boolean false Render the calendar right-to-left.
showMonthAfterYear Boolean false Show the month after the year in the title.
showDaysInNextAndPreviousMonths Boolean false Render days that fall in the adjoining months.
openByDefault Boolean false If true, the calendar is visible. If false, it is given display: none.
container Element or String null Element or selector to render the calendar into. When set, the calendar is not hidden.
showClearBtn Boolean false Show a Clear button in the footer.
autoSubmit Boolean true If true, selecting a day writes the input immediately. If false, Ok and Cancel buttons are added.
i18n Object See below Labels and month/weekday names. Partial objects are merged with the defaults.
events Array [] Strings from Date.toDateString(). Matching days get a has-event class. The default stylesheet does not style that class.
onSelect Function null Called when a date is selected. Receives the Date.
onDraw Function null Called after the calendar HTML is redrawn.
onInputInteraction Function null Called when the input is clicked or confirmed with Enter.
onConfirm Function null Called when the Ok button is used. Only created when autoSubmit is false.
onCancel Function null Called when the Cancel button is used. Only created when autoSubmit is false.
displayPlugin String null Set to 'docked' for a click-to-open popover. Pair with openByDefault: true.
displayPluginOptions Object null Options for the docked plugin: margin, transition, duration, align.

Date format options

Use these tokens in the format string.

Key Description Output
d Date of the month. 1–31
dd Date of the month, two digits. 01–31
ddd Weekday short name from i18n. Sun–Sat
dddd Weekday full name from i18n. Sunday–Saturday
m Month of the year. 1–12
mm Month of the year, two digits. 01–12
mmm Month short name from i18n. Jan–Dec
mmmm Month full name from i18n. January–December
yy Two-digit year. 26
yyyy Four-digit year. 2026

Internationalization

Pass a partial i18n object. Missing keys keep the English defaults.

Key Default
cancel 'Cancel'
clear 'Clear'
done 'Ok'
previousMonth '‹'
nextMonth '›'
months ['January', …, 'December']
monthsShort ['Jan', …, 'Dec']
weekdays ['Sunday', …, 'Saturday']
weekdaysShort ['Sun', …, 'Sat']
weekdaysAbbrev ['S', 'M', 'T', 'W', 'T', 'F', 'S']

Date range

Set isDateRange: true. Click a start day, then an end day that is on or after it. Point dateRangeEndEl at a second input, or omit it and a second input is created next to the first.

Expressive.Datepicker.init(document.getElementById('datepicker-range'), {
  openByDefault: true,
  isDateRange: true,
  dateRangeEndEl: '#datepicker-range-end'
});

Multiple dates

Set isMultipleSelection: true. Click a day to add it; click it again to remove it. Each selected date gets its own input.

Expressive.Datepicker.init(document.getElementById('datepicker-multi'), {
  openByDefault: true,
  isMultipleSelection: true
});

Methods

All methods are called on the plugin instance. You can get the instance like this:
const instance = Expressive.Datepicker.getInstance(elem);

The low-level renderRow, renderBody, and renderTable helpers accept only calendar rows, cells, and day buttons. Use renderDay to create cells. Unsupported elements or attributes, including event handlers and styles, throw TypeError; day buttons require type="button". Arbitrary custom HTML is no longer accepted.

.toString();

String form of the selected date, using format. You can pass another date and format.

instance.toString();
instance.toString(someDate, 'yyyy-mm-dd');
.setDate();

Select a date and move the calendar to it.

Date (optional): Date to select.

instance.setDate(new Date());
.gotoDate();

Change the visible month without changing the selection.

Date: Date whose month should be shown.

instance.gotoDate(new Date());
.destroy();

Destroy the plugin instance, remove the calendar, and tear down its event handlers.

instance.destroy();

Properties

Name Type Description
el Element The input the plugin was initialized with.
options Object The options the instance was initialized with.
date Date The selected date, or the range start.
endDate Date The range end, when isDateRange is true.
dates Array The selected dates when isMultipleSelection is true.
  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.