Forms Time Picker

Time Picker

An analog clock-face time picker built on wf-time-picker.js . Opens as a fixed-position dropdown showing a visual clock for hour selection followed by minute selection. Supports 12-hour (AM/PM) and 24-hour modes, configurable minute step increments, optional OK/Cancel/Now footer buttons, free-text or read-only input, and custom display formats.

Quick Start

Import the module once. All elements with data-wf-timepicker are enhanced automatically on DOMContentLoaded . The component adds a clock icon to the wrapper and seeds the panel from the input's current value. The default format is hh:mm tt (12-hour with AM/PM).

JS
import './wf-time-picker.js'
HTML
<!-- Auto-init (12-hour, default) -->
<div class="wf-timepicker" data-wf-timepicker>
  <input type="text" name="meeting_time" class="wf-input">
</div>

<!-- Manual init -->
<div class="wf-timepicker" id="my-tp">
  <input type="text" name="alarm_time" class="wf-input">
</div>
<script type="module">
  import { WojoTimePicker } from './wf-time-picker.js'
  new WojoTimePicker(document.getElementById('my-tp')).init()
</script>

24-Hour Mode

Add data-wf-is24 to switch to 24-hour mode. The AM/PM toggle is hidden from the header, and the hour ring shows both outer (1–12) and inner (13–24/00) labels. The default format automatically changes to HH:mm unless overridden with data-wf-format .

HTML
<!-- 12-hour (default) -->
<div class="wf-timepicker" data-wf-timepicker>
  <input type="text" name="time" class="wf-input">
</div>

<!-- 24-hour -->
<div class="wf-timepicker" data-wf-timepicker data-wf-is24>
  <input type="text" name="time" class="wf-input">
</div>

<!-- 24-hour with custom format -->
<div class="wf-timepicker" data-wf-timepicker data-wf-is24 data-wf-format="H:mm">
  <input type="text" name="time" class="wf-input">
</div>

Minute Steps

Use data-wf-minute-step to snap the minute hand to fixed increments. Supported values: 1 , 5 , 10 , 15 , 20 , 30 . Non-step minutes are visually dimmed and unclickable. The default step is 1 (every minute).

HTML
<!-- 15-minute steps -->
<div class="wf-timepicker" data-wf-timepicker data-wf-minute-step="15">
  <input type="text" name="slot" class="wf-input">
</div>

<!-- 30-minute steps -->
<div class="wf-timepicker" data-wf-timepicker data-wf-minute-step="30">
  <input type="text" name="slot" class="wf-input">
</div>

Footer Buttons

The panel footer shows Cancel and Now buttons by default. Add data-wf-ok-btn to defer the close until the user confirms. Set data-wf-cancel-btn="false" or data-wf-now-btn="false" to hide individual buttons. If no buttons remain, the footer is not rendered.

HTML
<!-- With OK button (defers close until confirmed) -->
<div class="wf-timepicker" data-wf-timepicker data-wf-ok-btn>
  <input type="text" name="time" class="wf-input">
</div>

<!-- No footer at all -->
<div class="wf-timepicker" data-wf-timepicker
     data-wf-now-btn="false"
     data-wf-cancel-btn="false">
  <input type="text" name="time" class="wf-input">
</div>

Format Tokens

The data-wf-format attribute controls the string written to the visible input when a time is confirmed. Combine tokens freely — any non-token characters are preserved as separators. The default format is hh:mm tt (12-hour) or HH:mm (24-hour).

Token Output Example
HH Zero-padded 24-hour 00–23
H 24-hour without padding 0–23
hh Zero-padded 12-hour 01–12
h 12-hour without padding 1–12
mm Zero-padded minutes 00–59
tt AM/PM uppercase AM, PM
t am/pm lowercase am, pm

Data Attributes

All configuration is applied via data-wf-* attributes on the .wf-timepicker wrapper.

Attribute Type Default Description
data-wf-timepicker Boolean - Required. Marks the wrapper for auto-init.
data-wf-format String hh:mm tt Display format string. Defaults to hh:mm tt (12h) or HH:mm when data-wf-is24 is set. Tokens: HH H hh h mm tt t.
data-wf-is24 Boolean - Switch to 24-hour mode. Hides AM/PM toggle; hour ring shows both outer (1–12) and inner (13–24/00) labels.
data-wf-minute-step Number 1 Minute snap increment. Supported values: 1, 5, 10, 15, 20, 30. Non-step minutes are dimmed and unclickable.
data-wf-ok-btn Boolean - Show an OK button in the footer. Defers the close until clicked — selecting a minute no longer auto-closes the panel.
data-wf-cancel-btn Boolean true Cancel button is shown by default. Set to "false" to hide it.
data-wf-now-btn Boolean true Now button is shown by default. Set to "false" to hide it. Clicking Now sets the current system time and closes the panel.
data-wf-read-only Boolean true The visible input is read-only by default (prevents keyboard entry). Set to "false" to allow free text entry.
data-wf-disabled Boolean - Disable all picker interaction. Adds wf-timepicker--disabled and sets disabled on the input.
Show More

Events & API

Access the instance via el._wfTimePicker after auto-init or manual new WojoTimePicker(el).init() .

Methods

Method Returns Description
tp.show() - Open the clock panel. Always opens on the hours view.
tp.hide() - Close the clock panel.
tp.toggle() - Toggle open/closed.
tp.getTime() { hour: number, minute: number } Returns the current internal time as a 24-hour hour (0–23) and minute (0–59), regardless of display format.
tp.setTime(str) - Parse and apply a formatted time string. Accepts "2:30 PM", "14:30", "02:30 am", etc.
tp.clearTime() - Clear the input value and emit wf:time-change with null values.
tp.setDisabled(bool) - Enable or disable the picker. Toggles wf-timepicker--disabled and the input's disabled attribute.
tp.destroy() - Remove the panel from the DOM and clean up all event listeners.

Events

All events are dispatched on the .wf-timepicker wrapper element.

Event Detail Description
wf:time-change { hour: number|null, minute: number|null, value: string|null } Fired when a time is confirmed (minute selected or OK clicked). All fields are null after clearTime(). hour is always 24-hour (0–23) regardless of display format.
wf:time-show - Fired when the clock panel opens.
wf:time-hide - Fired when the clock panel closes.
JS
// Access instance
const wrapper = document.querySelector('#my-tp')
const tp = wrapper._wfTimePicker

// Programmatic control
tp.setTime('2:30 PM')     // set from 12h string
tp.setTime('14:30')       // or 24h string
tp.getTime()              // -> { hour: 14, minute: 30 }
tp.clearTime()            // clear
tp.setDisabled(true)      // disable
tp.show()                 // open panel
tp.hide()                 // close panel
tp.destroy()              // remove component

// Listen for changes
wrapper.addEventListener('wf:time-change', e => {
  console.log(e.detail.hour)    // 0-23 (24h) or null
  console.log(e.detail.minute)  // 0-59 or null
  console.log(e.detail.value)   // formatted string or null
})