AdminKitDocs
Forms

Bootstrap 5 Datepicker

Bootstrap 5 datepicker with Vanilla Calendar Pro in AdminKit: an inline calendar, and in PRO a date, range and time picker that opens from an input.

A date picker lets people choose a date from a calendar instead of typing it. Use an inline calendar to show a month on a dashboard. Use a date picker on an input for a date field in a form.

AdminKit uses Vanilla Calendar Pro 3.4.0. In the free version, it draws the inline calendar of the Analytics dashboard. AdminKit PRO also styles the calendar as a popup that opens from an input, and adds a time picker.

The calendar follows the page's light or dark color mode. AdminKit colors it with the template's theme: the selected day is in the primary color, and today has a small corner marker.

Inline calendar

An inline calendar sits in the page and fills the width of its container, such as a card:

<div class="card mb-0">
  <div class="card-header">
    <h2 class="card-title mb-0">Calendar</h2>
  </div>
  <div class="card-body d-flex">
    <div class="align-self-center w-100">
      <div id="calendar-inline"></div>
    </div>
  </div>
</div>

<script>
new VanillaCalendar.Calendar("#calendar-inline", {
  selectedDates: [new Date()],
  enableJumpToSelectedDate: true,
  firstWeekday: 0,
  selectedTheme: "system",
  themeAttrDetect: "html[data-bs-theme]"
}).init();
</script>

selectedDates marks a date as selected, and enableJumpToSelectedDate opens the calendar on its month. firstWeekday: 0 starts the week on Sunday.

In a narrow card, such as a quarter-width column of a dashboard, the arrows, the title and the rows get smaller so the calendar still fits.

Use it in your page

js/app.js loads Vanilla Calendar Pro and makes it available as window.VanillaCalendar. There is nothing else to install. Unlike the charts and maps, the calendar has no AdminKit helper: you create it with new VanillaCalendar.Calendar(selector, options) and call init().

app.js is a module script, so it runs after the page has been parsed. The template's pages therefore create their calendars in a DOMContentLoaded listener, which runs after app.js:

<div id="datetimepicker-dashboard"></div>

<script>
  document.addEventListener("DOMContentLoaded", function () {
    new VanillaCalendar.Calendar("#datetimepicker-dashboard", {
      selectedDates: [new Date()],
      enableJumpToSelectedDate: true,
      firstWeekday: 0,
      selectedTheme: "system",
      themeAttrDetect: "html[data-bs-theme]"
    }).init();
  });
</script>

Always pass selectedTheme: "system" and themeAttrDetect: "html[data-bs-theme]". Together they make the calendar follow the data-bs-theme attribute that dark mode sets on <html>, also when someone switches modes while the page is open.

Date picker

Pro

This feature is only available in AdminKit PRO. Learn more.

For a date field in a form, attach the calendar to an input with inputMode: true. The calendar then opens as a popup when the input is clicked. You decide what the input shows: write the text in onChangeToInput, which the calendar calls when the selection changes.

<label class="form-label" for="datepicker-due">Due date</label>
<input type="text" class="form-control" id="datepicker-due" placeholder="Select date..">

<script>
  document.addEventListener("DOMContentLoaded", function () {
    new VanillaCalendar.Calendar("#datepicker-due", {
      inputMode: true,
      firstWeekday: 0,
      selectedTheme: "system",
      themeAttrDetect: "html[data-bs-theme]",
      onChangeToInput: function (self) {
        self.context.inputElement.value = self.context.selectedDates[0] || "";
        self.hide();
      }
    }).init();
  });
</script>

selectedDates holds the dates as "YYYY-MM-DD" strings. self.hide() closes the popup once a date is picked. The range picker leaves it open until you click outside it, so you can pick both ends.

The Advanced Inputs page builds all its pickers with the small datepicker() function above. It merges the shared options with the options of each picker.

Ranges, multiple dates and time

Pro

This feature is only available in AdminKit PRO. Learn more.

Some fields need several dates, a range, a time or both a date and a time. The Advanced Inputs page has a picker for each:

PickerOptionsWhat onChangeToInput writes
DatenoneselectedDates[0], then self.hide()
Readable datenoneThe date as "October 22, 2026", with toLocaleDateString()
Several datesselectionDatesMode: "multiple"selectedDates.join(", ")
Date rangeselectionDatesMode: "multiple-ranged"The first and last of selectedDates
Date and timeextensions: [VanillaCalendar.time], selectionTimeMode: 24The date, a space and selectedTime
Time onlyextensions: [VanillaCalendar.time], selectionTimeMode: 24, selectionDatesMode: false, layouts: { default: "<#ControlTime />" }selectedTime

The time picker is an extension of Vanilla Calendar Pro. AdminKit PRO makes it available as VanillaCalendar.time, and you turn it on per calendar with the extensions option. selectionTimeMode: 24 gives a 24-hour clock. A date and time picker:

new VanillaCalendar.Calendar("#datepicker-datetime", {
  inputMode: true,
  firstWeekday: 0,
  selectedTheme: "system",
  themeAttrDetect: "html[data-bs-theme]",
  extensions: [VanillaCalendar.time],
  selectionTimeMode: 24,
  onChangeToInput: function (self) {
    var date = self.context.selectedDates[0];
    self.context.inputElement.value = date ? date + " " + self.context.selectedTime : "";
  }
}).init();

The Vanilla Calendar Pro docs list every option.

Styles

AdminKit sets Vanilla Calendar Pro's --vc-* custom properties from the theme's --bs-* colors. Because those colors change with the color mode, so does the calendar. The styles are in src/scss/5-vendor/_vanilla-calendar.scss.

  • The inline calendar has a transparent background, so it takes the color of the card it sits in.
  • Its seven columns share the width evenly. The plugin's own minimum widths, made for a popup, are removed.
  • In AdminKit PRO, the popup gets the large border radius and the z-index of a dropdown. The time picker's colors come from the theme as well.

Accessibility

  • Give each date input a <label> with a for that matches the input's id, as in the examples above.
  • Vanilla Calendar Pro marks the input as opening a dialog (aria-haspopup="dialog"). In the calendar, the arrow keys move between the days, and Escape closes the popup.
  • The input text is whatever onChangeToInput writes. Show the expected format in the placeholder or in help text below the input.
  • People can still type in the input. Check the value on the server, or in your submit handler, before you use it.

Last updated on

On this page