Rewrote all the docs - more noob friendly now.
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -1,53 +1,18 @@
|
||||
# TimePicker
|
||||
|
||||
A styled time picker. The user selects hours, minutes, and optionally AM/PM. The component always writes the selected time as `HH:MM` (24-hour) to the hidden input, regardless of whether 12-hour display mode is used. Optionally renders a visible label and description.
|
||||
A styled time selector with separate dropdowns for hours and minutes (and optionally AM/PM). The selected time is always stored in a hidden input as `HH:MM` in 24-hour format, regardless of whether you show the 12-hour display mode.
|
||||
|
||||
---
|
||||
|
||||
## HTML structure
|
||||
## Quick example
|
||||
|
||||
```
|
||||
div.flex.flex-col.gap-1.5
|
||||
label.text-sm.font-medium ← omitted when empty
|
||||
{label}
|
||||
div.flex.items-center.gap-1.rounded-md.border.border-input.bg-background.px-3.py-2
|
||||
select.timepicker-h[name={name}-h] ← hour select (1–12 or 0–23)
|
||||
span.text-muted-foreground :
|
||||
select.timepicker-m[name={name}-m] ← minute select (00–59)
|
||||
select.timepicker-ampm[name={name}-ampm] ← AM/PM (12h mode only)
|
||||
input.sr-only[type=hidden, name={name}] ← hidden input holding HH:MM
|
||||
p.text-sm.text-muted-foreground ← omitted when empty
|
||||
{description}
|
||||
```csharp
|
||||
new TimePicker(name: "startTime", label: "Start time")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CSS mechanics
|
||||
|
||||
| Class | Effect |
|
||||
|---|---|
|
||||
| `rounded-md border border-input bg-background` | Consistent styling with other form fields |
|
||||
| `sr-only` on hidden input | Hidden visually but included in form submission |
|
||||
| `appearance-none` on `<select>` elements | Removes native browser dropdown arrow for uniform style |
|
||||
| `focus:outline-none` on selects | Focus ring deferred to the wrapper `div` |
|
||||
|
||||
---
|
||||
|
||||
## JavaScript (`syncTime` in `components.js`)
|
||||
|
||||
Runs on `DOMContentLoaded` and `htmx:afterSwap`.
|
||||
|
||||
### `syncTime(wrapper)`
|
||||
|
||||
1. Finds `.timepicker-h`, `.timepicker-m`, `.timepicker-ampm`, and the hidden `input`
|
||||
2. On any `change` event across the three visible selects:
|
||||
- Reads hour, minute, and AM/PM values
|
||||
- Converts 12h → 24h if AM/PM select is present
|
||||
- Writes `HH:MM` to the hidden input
|
||||
|
||||
---
|
||||
|
||||
## Constructor signature
|
||||
## All the options
|
||||
|
||||
```csharp
|
||||
public TimePicker(
|
||||
@@ -58,49 +23,24 @@ public TimePicker(
|
||||
bool use12h = false)
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| Parameter | What it does |
|
||||
|---|---|
|
||||
| `name` | Form field name; hidden input gets this name, visible selects get `{name}-h`, `{name}-m`, `{name}-ampm` |
|
||||
| `selected` | Pre-selected time as `"HH:MM"` (24h format); defaults to current time |
|
||||
| `label` | Optional visible label |
|
||||
| `description` | Optional helper text |
|
||||
| `use12h` | If `true`, shows AM/PM select and hour range 1–12 |
|
||||
| `name` | Form field name. The hidden input gets this name and always holds a `HH:MM` value. The visible selects get `{name}-h`, `{name}-m`, `{name}-ampm`. |
|
||||
| `selected` | Pre-selected time as `"HH:MM"` in 24-hour format. Defaults to the current time. |
|
||||
| `label` | Visible text label above the picker. |
|
||||
| `description` | Small hint text below the picker. |
|
||||
| `use12h` | Show 12-hour mode with an AM/PM dropdown. The hidden input still stores 24h format. |
|
||||
|
||||
---
|
||||
|
||||
## Usage examples
|
||||
## Real-world examples
|
||||
|
||||
### Basic time picker (24h)
|
||||
|
||||
```csharp
|
||||
new TimePicker(name: "startTime", label: "Start time")
|
||||
```
|
||||
|
||||
### 12-hour mode
|
||||
|
||||
```csharp
|
||||
new TimePicker(
|
||||
name: "meetingTime",
|
||||
label: "Meeting time",
|
||||
use12h: true)
|
||||
```
|
||||
|
||||
### Pre-selected time
|
||||
|
||||
```csharp
|
||||
new TimePicker(
|
||||
name: "alarmTime",
|
||||
selected: "07:30",
|
||||
label: "Alarm",
|
||||
use12h: true)
|
||||
```
|
||||
|
||||
### Inside a form
|
||||
### Appointment booking with start and end times
|
||||
|
||||
```html
|
||||
<!-- ScheduleForm.htmx -->
|
||||
<form method="post" action="/schedule">
|
||||
$$AntiforgeryToken$$
|
||||
<form method="post" action="/schedule" class="space-y-4">
|
||||
$$Token$$
|
||||
$$StartTime$$
|
||||
$$EndTime$$
|
||||
<button type="submit">Save</button>
|
||||
@@ -108,16 +48,40 @@ new TimePicker(
|
||||
```
|
||||
|
||||
```csharp
|
||||
public ScheduleForm()
|
||||
{
|
||||
StartTime = new TimePicker(name: "startTime", label: "Start", selected: "09:00");
|
||||
EndTime = new TimePicker(name: "endTime", label: "End", selected: "17:00");
|
||||
}
|
||||
// ScheduleForm.htmx.cs
|
||||
_startTime = new TimePicker(name: "startTime", label: "Start", selected: "09:00");
|
||||
_endTime = new TimePicker(name: "endTime", label: "End", selected: "17:00");
|
||||
```
|
||||
|
||||
**Reading the submitted values:**
|
||||
Reading on the server:
|
||||
|
||||
```csharp
|
||||
public record Command(
|
||||
[property: FromForm] string StartTime, // "HH:MM"
|
||||
[property: FromForm] string EndTime
|
||||
);
|
||||
|
||||
var start = TimeOnly.ParseExact(command.StartTime, "HH:mm");
|
||||
var end = TimeOnly.ParseExact(command.EndTime, "HH:mm");
|
||||
```
|
||||
|
||||
### 12-hour display mode with a pre-selected time
|
||||
|
||||
```csharp
|
||||
new TimePicker(
|
||||
name: "alarmTime",
|
||||
selected: "07:30",
|
||||
label: "Alarm time",
|
||||
use12h: true)
|
||||
```
|
||||
|
||||
The user sees `7:30 AM` in the dropdowns, but `07:30` is what gets submitted.
|
||||
|
||||
---
|
||||
|
||||
## How it works
|
||||
|
||||
TimePicker renders three `<select>` elements (hours, minutes, and optionally AM/PM) styled to look like a single field, plus a hidden `<input>` that holds the combined value. JavaScript in `components.js` listens for changes on any of the three selects and writes the correctly formatted `HH:MM` value to the hidden input, converting from 12h to 24h when needed.
|
||||
public record Command(
|
||||
[property: FromForm] string StartTime, // "09:00"
|
||||
[property: FromForm] string EndTime // "17:00"
|
||||
|
||||
Reference in New Issue
Block a user