Datepicker
A flexible calendar and date picker popover with support for input or button toggles, range selection, multiple months, and more.
Overview
The Bootstrap Datepicker is a wrapper around Vanilla Calendar Pro that provides a consistent, accessible date selection experience. It supports light/dark themes, input binding, and flexible configuration via data attributes or JavaScript.
<label for="datepicker1" class="form-label">Datepicker</label>
<input type="text" class="form-input w-12" id="datepicker1" data-cx-toggle="datepicker" placeholder="Choose date…">Note that we’re using a width utility of .w-12 to ensure the input is wide enough to accommodate the date format and imply some affordance for the expected type of input.
How it works
- Add
data-cx-toggle="datepicker"to any<input>element to enable the datepicker - Use
type="text"to avoid conflicts with native browser date pickers - When focused, the calendar popup appears below the input
- Selecting a date updates the input value and closes the picker
- The picker respects Bootstrap’s color modes (
data-cx-theme) - Configurable with any Vanilla Calendar Pro option via
vcpOptionswhen initializing with JavaScript
Examples
With form field
Use the form field component to layout and wrap your inputs with a label, description, and validation feedback messages in a vertical stack.
<div class="form-field">
<label for="datepicker2" class="form-label">Datepicker field</label>
<input type="text" class="form-input w-12" id="datepicker2" data-cx-toggle="datepicker" placeholder="Choose date…">
<div class="form-text">
We’ll never share your email with anyone else.
</div>
</div>With icon
Use the form adorn component to add a calendar icon alongside the datepicker input. When the input is inside a .form-adorn wrapper, the calendar automatically positions relative to the wrapper instead of the input.
<label for="datepickerIconStart" class="form-label">Select date</label>
<div class="form-input w-12">
<div class="input-help">
<svg class="icon" aria-hidden="true"><use href="#calendar-solid"></use></svg>
</div>
<input type="text" class="ghost-input" id="datepickerIconStart" data-cx-toggle="datepicker" placeholder="Choose date…">
</div>Min & Max dates
Restrict the selectable date range using data-cx-date-min and data-cx-date-max.
<label for="datepickerMinMax" class="form-label">Event date (2026 only)</label>
<input type="text" class="form-input w-12" id="datepickerMinMax" data-cx-toggle="datepicker" data-cx-date-min="2026-01-01" data-cx-date-max="2026-12-31" placeholder="Select a date in 2026">Multiple dates
Enable multiple date selection with data-cx-selection-mode="multiple".
<label for="datepicker3" class="form-label">Select multiple dates</label>
<input type="text" class="form-input" id="datepicker3" data-cx-toggle="datepicker" data-cx-selection-mode="multiple" placeholder="Select date range…">Multiple months
Display multiple months side-by-side with the displayMonthsCount option. This is useful for date range selection where users need to see more context.
<label for="datepickerMultiMonth" class="form-label">Select date range</label>
<input type="text" class="form-input" id="datepickerMultiMonth" data-cx-toggle="datepicker" data-cx-selection-mode="multiple-ranged" data-cx-display-months-count="2" placeholder="Select start and end dates">Date range
Select a range of dates with data-cx-selection-mode="multiple-ranged". Use data-cx-selected-dates to preselect a date range.
<label for="datepicker4" class="form-label">Select date range</label>
<input type="text" class="form-input" id="datepicker4" data-cx-toggle="datepicker" data-cx-selection-mode="multiple-ranged" data-cx-selected-dates='["2026-06-10", "2026-06-18"]' placeholder="Select start and end dates…">Multi-month date range
For selecting date ranges that span multiple months, combine data-cx-selection-mode="multiple-ranged" with data-cx-display-months-count="2" to show two months side-by-side, making it easier for users to select across month boundaries.
<label for="datepickerRangeTwoMonths" class="form-label">Select date range</label>
<input type="text" class="form-input" id="datepickerRangeTwoMonths" data-cx-toggle="datepicker" data-cx-selection-mode="multiple-ranged" data-cx-display-months-count="2" data-cx-selected-dates='["2026-06-25", "2026-07-08"]' placeholder="Select start and end dates…">Options
First day of week
Set the first day of the week (0 = Sunday, 1 = Monday, etc.) with data-cx-first-weekday.
<label for="datepicker6" class="form-label">Week starts on Sunday</label>
<input type="text" class="form-input w-12" id="datepicker6" data-cx-toggle="datepicker" data-cx-first-weekday="0" placeholder="Select a date">Placement
Control where the calendar appears relative to the input with data-cx-placement. Options are left (default), center, right, and auto.
<div class="d-flex gap-medium">
<div>
<label for="datepickerLeft" class="form-label">Left aligned</label>
<input type="text" class="form-input" id="datepickerLeft" data-cx-toggle="datepicker" data-cx-placement="left" placeholder="Left">
</div>
<div>
<label for="datepickerCenter" class="form-label">Center aligned</label>
<input type="text" class="form-input" id="datepickerCenter" data-cx-toggle="datepicker" data-cx-placement="center" placeholder="Center">
</div>
<div>
<label for="datepickerRight" class="form-label">Right aligned</label>
<input type="text" class="form-input" id="datepickerRight" data-cx-toggle="datepicker" data-cx-placement="right" placeholder="Right">
</div>
</div>Button trigger
Use a button instead of an input for use cases like dashboard date filters. Add data-cx-datepicker-display to the text element to preserve icons when the date updates.
<button type="button" class="button outline secondary" data-cx-toggle="datepicker">
<svg class="icon" aria-hidden="true"><use href="#calendar-solid"></use></svg>
<span data-cx-datepicker-display>Select date</span>
</button>For date range selection (e.g., dashboard time filters), use data-cx-selection-mode="multiple-ranged". The calendar will close after both start and end dates are selected.
<button type="button" class="button outline secondary" data-cx-toggle="datepicker" data-cx-selection-mode="multiple-ranged">
<svg class="icon" aria-hidden="true"><use href="#calendar-solid"></use></svg>
<span data-cx-datepicker-display>Last 7 days</span>
</button>You can also display the selected date in a separate element using the displayElement option via JavaScript:
const datepicker = new bootstrap.Datepicker(buttonElement, {
selectionMode: 'multiple-ranged',
displayElement: '#date-display' // Selector or element
})Inline mode
Render the calendar inline (always visible, no popup) with data-cx-inline="true". This is useful for embedding a calendar directly in the page.
<div data-cx-toggle="datepicker" data-cx-inline="true"></div>Inline datepickers with date range selection:
<div data-cx-toggle="datepicker" data-cx-inline="true" data-cx-selection-mode="multiple-ranged"></div>Multiple months inline:
<div data-cx-toggle="datepicker" data-cx-inline="true" data-cx-display-months-count="2"></div>To bind to a form field, include a hidden input inside the container. The value will be updated with the selected date(s) in YYYY-MM-DD format:
<form>
<div data-cx-toggle="datepicker" data-cx-inline="true">
<input type="hidden" name="selected_date">
</div>
<button type="submit" class="button solid primary mt-medium">Submit</button>
</form>Custom date formatting
Control how dates are displayed using the dateFormat option. Pass an Intl.DateTimeFormat options object or a custom function.
// Using Intl.DateTimeFormat options
const datepicker = new bootstrap.Datepicker(element, {
dateFormat: { month: 'short', day: 'numeric', year: 'numeric' }
// Output: "Dec 23, 2026 – Dec 28, 2026"
})
// Using a custom function
const datepicker = new bootstrap.Datepicker(element, {
dateFormat: (date, locale) => {
return date.toLocaleDateString(locale, { month: 'short', day: 'numeric' })
}
// Output: "Dec 23 – Dec 28"
})Dark mode
The datepicker automatically adapts to Bootstrap’s color modes. When data-cx-theme="dark" is set on a parent element or the <html> tag, the calendar popup inherits that theme.
Inherited from parent
When a parent element has a theme, both the input and calendar popup inherit it:
<div data-cx-theme="dark" class="p-medium bg-body fg-body rounded">
<label for="datepickerDark" class="form-label">Dark mode datepicker</label>
<input type="text" class="form-input" id="datepickerDark" data-cx-toggle="datepicker" placeholder="Select a date">
</div>Datepicker-only theme
Use data-cx-datepicker-theme to set the datepicker popup’s theme independently of the input. This is useful when you want a light input with a dark datepicker, or vice versa:
<label for="datepickerTheme" class="form-label">Light input, dark datepicker</label>
<input type="text" class="form-input w-12" id="datepickerTheme" data-cx-toggle="datepicker" data-cx-datepicker-theme="dark" placeholder="Select a date">CSS
Variables
--cx-padding-x: var(--cx-datepicker-padding-x, 0.5rem);
--cx-padding-y: var(--cx-datepicker-padding-y, 0.5rem);
--cx-bg-color: var(--cx-datepicker-bg-color, var(--cx-default-bg-main));
--cx-fg-color: var(--cx-datepicker-fg-color, var(--cx-default-fg-main));
--cx-border-color: var(--cx-datepicker-border-color, var(--cx-default-transparent-color));
--cx-border-width: var(--cx-datepicker-border-width, var(--cx-border-width-medium));
--cx-border-radius: var(--cx-datepicker-border-radius, var(--cx-border-radius-medium));
--cx-day-border-radius: var(--cx-datepicker-day-border-radius, var(--cx-border-radius-small));
--cx-box-shadow: var(--cx-datepicker-box-shadow, var(--cx-box-shadow-medium));
--cx-font-size: var(--cx-datepicker-font-size, var(--cx-font-size-small));
--cx-today-font-weight: var(--cx-datepicker-today-font-weight, var(--cx-font-weight-strong));
--cx-min-width: var(--cx-datepicker-min-width, 7.5rem);
--cx-zindex: var(--cx-datepicker-zindex, 1000);
--cx-header-font-size: var(--cx-datepicker-header-header-font-size, var(--cx-font-size-small));
--cx-header-font-weight: var(--cx-datepicker-header-header-font-weight, var(--cx-font-weight-strong));
--cx-weekday-fg-color: var(--cx-datepicker-weekday-fg-color, var(--cx-default-fg-main));
--cx-day-hover-bg-color: var(--cx-datepicker-day-hover-bg-color, var(--cx-default-bg-even));
--cx-day-selected-bg-color: var(--cx-datepicker-day-selected-bg-color, var(--cx-default-cue-main));
--cx-day-selected-fg-color: var(--cx-datepicker-day-selected-fg-color, var(--cx-white-base-color));
--cx-day-range-bg-color: var(--cx-datepicker-day-range-bg-color, var(--cx-default-bg-highlight));
--cx-day-range-fg-color: var(--cx-datepicker-day-range-fg-color, var(--cx-default-fg-idle));
--cx-day-today-bg-color: var(--cx-datepicker-day-today-bg-color, var(--cx-default-transparent-color));
--cx-day-today-fg-color: var(--cx-datepicker-day-today-fg-color, var(--cx-default-cue-main));
--cx-day-weekend-bg-color: var(--cx-datepicker-day-weekend-bg-color, var(--cx-default-transparent-color));
--cx-day-weekend-fg-color: var(--cx-datepicker-day-weekend-fg-color, var(--cx-default-fg-subtle));
--cx-day-disabled-fg-color: var(--cx-datepicker-day-disabled-fg-color, var(--cx-default-fg-slight));Usage
Via data attributes
Add data-cx-toggle="datepicker" to any input element to initialize it as a datepicker.
| Attribute | Description |
|---|---|
data-cx-toggle="datepicker" | Initializes the datepicker on the input (or button) element. |
data-cx-inline | When true, renders the calendar inline instead of a popup. |
<input type="text" class="form-input" data-cx-toggle="datepicker">Via JavaScript
Initialize datepickers programmatically:
const datepickerEl = document.getElementById('myDatepicker')
const datepicker = new bootstrap.Datepicker(datepickerEl, {
selectionMode: 'single',
firstWeekday: 1
})Options
| Name | Type | Default | Description |
|---|---|---|---|
dateMin | string, number, Date | null | Minimum selectable date. Format: YYYY-MM-DD |
dateMax | string, number, Date | null | Maximum selectable date. Format: YYYY-MM-DD |
dateFormat | object, function | null | Date formatting. Pass Intl.DateTimeFormat options or a function(date, locale). |
displayElement | string, element, boolean | null | Element to show formatted date. For buttons, defaults to the button itself. Set to false to disable. |
displayMonthsCount | number | 1 | Number of months to display side-by-side in the calendar. |
firstWeekday | number | 1 | First day of week (0 = Sunday, 1 = Monday, etc.) |
inline | boolean | false | Render calendar inline (always visible, no popup). |
locale | string | 'default' | Locale for date formatting (e.g., 'en-US', 'de-DE') |
positionElement | string, element | null | Element to position calendar relative to. Auto-detects .form-adorn wrapper if present. |
selectedDates | array | [] | Pre-selected dates in YYYY-MM-DD format |
selectionMode | string | 'single' | Selection mode: 'single', 'multiple', or 'multiple-ranged' |
placement | string | 'left' | Calendar position relative to input: 'left', 'center', 'right', 'auto' |
datepickerTheme | string | null | Force datepicker popup theme: 'light', 'dark', 'auto', or null to inherit from ancestor [data-cx-theme] |
vcpOptions | object | {} | Pass-through object for any Vanilla Calendar Pro option |
Advanced configuration
For features not directly exposed by Bootstrap’s options, use vcpOptions to pass any Vanilla Calendar Pro setting:
const datepicker = new bootstrap.Datepicker(element, {
vcpOptions: {
disableDatesPast: true, // Disable past dates
disableWeekdays: [0, 6], // Disable weekends
disableDates: ['2026-12-25', '2026-12-26'], // Disable specific dates
selectedHolidays: ['2026-01-01'], // Highlight holidays
selectionTimeMode: 24 // Enable 24-hour time selection
}
})See the Vanilla Calendar Pro documentation for all available options.
Methods
| Method | Description |
|---|---|
show() | Shows the datepicker calendar |
hide() | Hides the datepicker calendar |
toggle() | Toggles the datepicker visibility |
getSelectedDates() | Returns an array of selected dates in YYYY-MM-DD format |
setSelectedDates(dates) | Sets the selected dates. Expects an array of YYYY-MM-DD strings |
dispose() | Destroys the datepicker instance |
getInstance(element) | Static method to get the datepicker instance from a DOM element |
getOrCreateInstance(element) | Static method to get or create a datepicker instance |
Events
| Event | Description |
|---|---|
show.bs.datepicker | Fires immediately when the show method is called |
shown.bs.datepicker | Fires when the datepicker has been made visible |
hide.bs.datepicker | Fires immediately when the hide method is called |
hidden.bs.datepicker | Fires when the datepicker has been hidden |
change.bs.datepicker | Fires when a date is selected. Event includes dates (array) and event properties |
const datepickerEl = document.getElementById('myDatepicker')
datepickerEl.addEventListener('change.bs.datepicker', event => {
console.log('Selected dates:', event.dates)
})