Data inputExtension
Date & Time Picker
Choose a date and a time in one field, from a popup with a calendar and time columns, or type DD/MM/YYYY HH:MM.
| Class name | Type | Description |
|---|---|---|
date-pickerplf:date-picker | Component | Wraps the native input and the controls |
calendarplf:calendar | Component | The Calendar in the panel |
input-groupplf:input-group | Component | The text field with its trigger |
date-picker-controlsplf:date-picker-controls | Part | The hidden controls the script shows |
date-picker-fieldplf:date-picker-field | Part | The text field's Field |
date-picker-panelplf:date-picker-panel | Part | The Popover panel |
date-time-picker-panelplf:date-time-picker-panel | Part | Widens the panel for the time columns |
date-time-picker-bodyplf:date-time-picker-body | Part | The calendar beside the time columns |
date-time-picker-timeplf:date-time-picker-time | Part | The time columns' box the script adds, or an empty one the page places |
date-picker-footerplf:date-picker-footer | Part | The panel's buttons |
input-group-actionplf:input-group-action | Part | The button that opens the panel, which draws a calendar |
input-group-addonplf:input-group-addon | Part | Joins the button as a segment |
input-group-iconplf:input-group-icon | Part | Your own SVG, in place of the drawn calendar; an icon class there doesn't need it |
input-group-controlplf:input-group-control | Part | The text field |
Default
The native input needs a unique id and a name; the text field has no name and needs a label.
Any minute, in your local time. Bookings open from 5 October 2026, 08:00.
<div class="date-picker" data-plf-date-time-picker>
<label class="field" for="date-time-input">
<span class="field-label">Appointment</span>
<input class="input" id="date-time-input" name="appointment" type="datetime-local" value="2026-10-12T09:30" min="2026-10-05T08:00" max="2027-12-31T18:00" required>
</label>
<div class="date-picker-controls" hidden>
<div class="popover" data-plf-popover data-plf-align="start">
<div class="field date-picker-field">
<label class="field-label" for="date-time-text">Appointment</label>
<div class="input-group">
<button type="button" class="input-group-action input-group-addon" aria-label="Open date and time picker"></button>
<input class="input-group-control" type="text" id="date-time-text" aria-describedby="date-time-help">
</div>
</div>
<div class="popover-content date-picker-panel date-time-picker-panel" aria-label="Choose appointment date and time" hidden>
<div class="date-time-picker-body">
<div class="calendar" data-plf-calendar data-plf-today="2026-10-04"></div>
</div>
<div class="date-picker-footer">
<button type="button" class="btn btn-ghost btn-sm" data-plf-popover-close>Cancel</button>
<button type="button" class="btn btn-outline btn-sm" data-plf-date-time-picker-clear>Clear</button>
<button type="button" class="btn btn-primary btn-sm" data-plf-date-time-picker-apply>Apply</button>
</div>
</div>
</div>
</div>
</div>
<p class="field-help" id="date-time-help">Any minute, in your local time. Bookings open from 5 October 2026, 08:00.</p><div class="plf:date-picker" data-plf-date-time-picker>
<label class="plf:field" for="date-time-input">
<span class="plf:field-label">Appointment</span>
<input class="plf:input" id="date-time-input" name="appointment" type="datetime-local" value="2026-10-12T09:30" min="2026-10-05T08:00" max="2027-12-31T18:00" required>
</label>
<div class="plf:date-picker-controls" hidden>
<div class="plf:popover" data-plf-popover data-plf-align="start">
<div class="plf:field plf:date-picker-field">
<label class="plf:field-label" for="date-time-text">Appointment</label>
<div class="plf:input-group">
<button type="button" class="plf:input-group-action plf:input-group-addon" aria-label="Open date and time picker"></button>
<input class="plf:input-group-control" type="text" id="date-time-text" aria-describedby="date-time-help">
</div>
</div>
<div class="plf:popover-content plf:date-picker-panel plf:date-time-picker-panel" aria-label="Choose appointment date and time" hidden>
<div class="plf:date-time-picker-body">
<div class="plf:calendar" data-plf-calendar data-plf-today="2026-10-04"></div>
</div>
<div class="plf:date-picker-footer">
<button type="button" class="plf:btn plf:btn-ghost plf:btn-sm" data-plf-popover-close>Cancel</button>
<button type="button" class="plf:btn plf:btn-outline plf:btn-sm" data-plf-date-time-picker-clear>Clear</button>
<button type="button" class="plf:btn plf:btn-primary plf:btn-sm" data-plf-date-time-picker-apply>Apply</button>
</div>
</div>
</div>
</div>
</div>
<p class="plf:field-help" id="date-time-help">Any minute, in your local time. Bookings open from 5 October 2026, 08:00.</p>Seconds
The time columns follow the native step in seconds: 900 shows quarter hours, and a step below 60 adds a Second column.
<div class="date-picker" data-plf-date-time-picker>
<label class="field" for="date-time-lap-input">
<span class="field-label">Lap start</span>
<input class="input" id="date-time-lap-input" name="lap" type="datetime-local" value="2026-10-12T09:30:15" step="1">
</label>
<div class="date-picker-controls" hidden>
<div class="popover" data-plf-popover data-plf-align="start">
<div class="field date-picker-field">
<label class="field-label" for="date-time-lap-text">Lap start</label>
<div class="input-group">
<button type="button" class="input-group-action input-group-addon" aria-label="Open date and time picker"></button>
<input class="input-group-control" type="text" id="date-time-lap-text">
</div>
</div>
<div class="popover-content date-picker-panel date-time-picker-panel" aria-label="Choose lap start date and time" hidden>
<div class="date-time-picker-body">
<div class="calendar" data-plf-calendar data-plf-today="2026-10-04"></div>
</div>
<div class="date-picker-footer">
<button type="button" class="btn btn-ghost btn-sm" data-plf-popover-close>Cancel</button>
<button type="button" class="btn btn-outline btn-sm" data-plf-date-time-picker-clear>Clear</button>
<button type="button" class="btn btn-primary btn-sm" data-plf-date-time-picker-apply>Apply</button>
</div>
</div>
</div>
</div>
</div><div class="plf:date-picker" data-plf-date-time-picker>
<label class="plf:field" for="date-time-lap-input">
<span class="plf:field-label">Lap start</span>
<input class="plf:input" id="date-time-lap-input" name="lap" type="datetime-local" value="2026-10-12T09:30:15" step="1">
</label>
<div class="plf:date-picker-controls" hidden>
<div class="plf:popover" data-plf-popover data-plf-align="start">
<div class="plf:field plf:date-picker-field">
<label class="plf:field-label" for="date-time-lap-text">Lap start</label>
<div class="plf:input-group">
<button type="button" class="plf:input-group-action plf:input-group-addon" aria-label="Open date and time picker"></button>
<input class="plf:input-group-control" type="text" id="date-time-lap-text">
</div>
</div>
<div class="plf:popover-content plf:date-picker-panel plf:date-time-picker-panel" aria-label="Choose lap start date and time" hidden>
<div class="plf:date-time-picker-body">
<div class="plf:calendar" data-plf-calendar data-plf-today="2026-10-04"></div>
</div>
<div class="plf:date-picker-footer">
<button type="button" class="plf:btn plf:btn-ghost plf:btn-sm" data-plf-popover-close>Cancel</button>
<button type="button" class="plf:btn plf:btn-outline plf:btn-sm" data-plf-date-time-picker-clear>Clear</button>
<button type="button" class="plf:btn plf:btn-primary plf:btn-sm" data-plf-date-time-picker-apply>Apply</button>
</div>
</div>
</div>
</div>
</div>JavaScript
Date & Time Picker needs JavaScript and is an extension: the Full script and Full CSS leave it out. The Full script (pelatform-ui.min.js) and the extension scripts after it start every component on page load, with no code of your own; with Core and single files, the last line starts them. For markup you add later, see Dynamic content.
<link rel="stylesheet" href="pelatform-ui.min.css">
<link rel="stylesheet" href="extensions/calendar.min.css">
<link rel="stylesheet" href="extensions/date-picker.min.css">
<link rel="stylesheet" href="extensions/date-time-picker.min.css">
<script src="pelatform-ui.min.js" defer></script>
<script src="extensions/calendar.min.js" defer></script>
<script src="extensions/date-time-picker.min.js" defer></script><link rel="stylesheet" href="core/pelatform-ui-core.min.css">
<link rel="stylesheet" href="components/button.min.css">
<link rel="stylesheet" href="components/form.min.css">
<link rel="stylesheet" href="components/popover.min.css">
<link rel="stylesheet" href="components/select.min.css">
<link rel="stylesheet" href="extensions/calendar.min.css">
<link rel="stylesheet" href="extensions/date-picker.min.css">
<link rel="stylesheet" href="extensions/date-time-picker.min.css">
<script src="core/pelatform-ui-core.min.js" defer></script>
<script src="components/popover.min.js" defer></script>
<script src="components/select.min.js" defer></script>
<script src="extensions/calendar.min.js" defer></script>
<script src="extensions/date-time-picker.min.js" defer></script>
<script>document.addEventListener('DOMContentLoaded', () => PLF.init());</script><link rel="stylesheet" href="pelatform-ui.prefixed.min.css">
<link rel="stylesheet" href="extensions/calendar.prefixed.min.css">
<link rel="stylesheet" href="extensions/date-picker.prefixed.min.css">
<link rel="stylesheet" href="extensions/date-time-picker.prefixed.min.css">
<script src="pelatform-ui.min.js" defer></script>
<script src="extensions/calendar.min.js" defer></script>
<script src="extensions/date-time-picker.min.js" defer></script><link rel="stylesheet" href="core/pelatform-ui-core.prefixed.min.css">
<link rel="stylesheet" href="components/button.prefixed.min.css">
<link rel="stylesheet" href="components/form.prefixed.min.css">
<link rel="stylesheet" href="components/popover.prefixed.min.css">
<link rel="stylesheet" href="components/select.prefixed.min.css">
<link rel="stylesheet" href="extensions/calendar.prefixed.min.css">
<link rel="stylesheet" href="extensions/date-picker.prefixed.min.css">
<link rel="stylesheet" href="extensions/date-time-picker.prefixed.min.css">
<script src="core/pelatform-ui-core.min.js" defer></script>
<script src="components/popover.min.js" defer></script>
<script src="components/select.min.js" defer></script>
<script src="extensions/calendar.min.js" defer></script>
<script src="extensions/date-time-picker.min.js" defer></script>
<script>document.addEventListener('DOMContentLoaded', () => PLF.init());</script>With ESM imports, import DateTimePicker from @pelatform/ui/extensions/date-time-picker and call use(DateTimePicker) before init().
Hooks
| Attribute | Purpose |
|---|---|
data-plf-date-time-picker |
The date-picker wrapper |
<input type="datetime-local"> |
The named native input, which keeps the value and works without the script; its field, the wrapper’s child around it, hides once the text field works |
data-plf-popover |
Holds the field, its first child, and the panel, written hidden. The field holds the calendar button, the Popover’s trigger, and the text field: an unnamed, labeled text input, beside the button in one group such as an Input Group. Unless written, the script gives it the placeholder DD/MM/YYYY HH:, with : for seconds, and no autofill |
data-plf-date-time-picker-time |
Optional; on an empty date-time-picker-time, places the time columns there instead of after the calendar |
data-plf-hour-label, data-plf-minute-label, data-plf-second-label |
On the wrapper: translated column headings; Hour, Minute and Second by default |
data-plf-date-time-picker-clear, data-plf-date-time-picker-apply |
Optional <button type="button"> in the panel: empty the value, or commit the draft |
min, max, required, readonly, disabled |
On the native input: apply to the whole picker |
| Method | Behavior |
|---|---|
PLF. |
Returns the instance, creating it for valid markup |
PLF. |
Returns the instance or null |
instance. |
Returns {value, draft, open} |
instance. |
Sets a YYYY-MM-DDTHH: value, or null to clear; returns false when unchanged, out of bounds or canceled |
instance. |
Empties the value |
instance., instance. |
Open or close the popup; return false when nothing changes |
instance. |
Removes the time columns and error, restores the native field, and leaves Calendar and Popover instances it did not create |
| Event | When |
|---|---|
plf: |
Before a new value; cancelable |
plf: |
After the new value is kept |
Each event’s detail:
| Property | Value |
|---|---|
instance |
The Date & Time Picker instance |
reason |
trigger or api |
trigger |
The control that set the value, such as the text field, a time option, the clear button or the apply button, or null from a method |
previousValue |
The value before, YYYY-MM-DDTHH: with : for seconds, or null when empty |
value |
The new value, YYYY-MM-DDTHH: with : for seconds, or null when empty |
The native input also fires input and change.
Keyboard
| Key | Action |
|---|---|
| Alt + Arrow Down | In the field, opens the popup with focus on the calendar |
| Enter | In the field, applies the typed value; in a time column, chooses the option |
| Escape | In the field, restores the current text; in the popup, closes it without changing the value |
| Arrow Up, Arrow Down, Home, End | Move through the enabled options of a time column |
| Space | In a time column, chooses the option |
Calendar days use the Calendar keys.
| Variable | Default |
|---|---|
--plf-date-time-picker-width |
31rem (496px), or 35rem (560px) with a Second column; never wider than the viewport |
--plf-date-time-picker-column-height |
6. (104px), the compact time wheel on narrow screens |
--plf-date-time-picker-hover-bg |
--plf-color-surface-muted |
--plf-date-time-picker-selected-bg |
--plf-color-primary |
--plf-date-time-picker-selected-color |
--plf-color-on-primary |