155 lines
4.1 KiB
Markdown
155 lines
4.1 KiB
Markdown
# DatePicker Component
|
|
|
|
A reusable, standalone date picker component for oslstats forms.
|
|
|
|
## Features
|
|
|
|
✨ **Interactive Calendar**
|
|
- Click-to-open dropdown calendar
|
|
- Month and year dropdown selectors for easy navigation
|
|
- Previous/next month arrow buttons
|
|
- Today's date highlighted in blue
|
|
|
|
📅 **Date Format**
|
|
- DD/MM/YYYY format (the sensible way)
|
|
- Pattern validation built-in
|
|
- Read-only input (date selection via picker only)
|
|
|
|
🎨 **Design**
|
|
- Consistent with Catppuccin theme
|
|
- Responsive layout
|
|
- Hover effects and visual feedback
|
|
- Calendar icon in input field
|
|
|
|
🔧 **Technical**
|
|
- Built with Alpine.js (already in project)
|
|
- No external dependencies
|
|
- Year range: 2001-2051
|
|
- Submits in DD/MM/YYYY format
|
|
|
|
## Usage
|
|
|
|
### Basic Example
|
|
|
|
```templ
|
|
import "git.haelnorr.com/h/oslstats/internal/view/component/datepicker"
|
|
|
|
// Simple usage - required field, no custom onChange
|
|
@datepicker.DatePicker(
|
|
"event_date", // id
|
|
"event_date", // name
|
|
"Event Date", // label
|
|
"DD/MM/YYYY", // placeholder
|
|
true, // required
|
|
"" // onChange (empty = none)
|
|
)
|
|
```
|
|
|
|
### With Custom onChange Handler
|
|
|
|
```templ
|
|
// With Alpine.js validation logic
|
|
@datepicker.DatePicker(
|
|
"start_date",
|
|
"start_date",
|
|
"Start Date",
|
|
"DD/MM/YYYY",
|
|
true,
|
|
"dateIsEmpty = false; validateForm();"
|
|
)
|
|
```
|
|
|
|
### Optional Field
|
|
|
|
```templ
|
|
// Non-required field
|
|
@datepicker.DatePicker(
|
|
"end_date",
|
|
"end_date",
|
|
"End Date (Optional)",
|
|
"DD/MM/YYYY",
|
|
false, // not required
|
|
""
|
|
)
|
|
```
|
|
|
|
## Parameters
|
|
|
|
| Parameter | Type | Description | Example |
|
|
|-------------|--------|------------------------------------------------------|----------------------------------|
|
|
| `id` | string | Unique ID for the input element | `"start_date"` |
|
|
| `name` | string | Form field name (used in form submission) | `"start_date"` |
|
|
| `label` | string | Display label above the input | `"Start Date"` |
|
|
| `placeholder` | string | Placeholder text in the input | `"DD/MM/YYYY"` |
|
|
| `required` | bool | Whether the field is required | `true` or `false` |
|
|
| `onChange` | string | Alpine.js expression to run when date changes | `"updateForm();"` or `""` |
|
|
|
|
## Server-Side Parsing
|
|
|
|
The date picker submits dates in **DD/MM/YYYY** format. Parse on the server like this:
|
|
|
|
```go
|
|
import "time"
|
|
|
|
// Parse DD/MM/YYYY format
|
|
dateStr := r.FormValue("start_date") // e.g., "15/02/2026"
|
|
date, err := time.Parse("02/01/2006", dateStr)
|
|
if err != nil {
|
|
// Handle invalid date
|
|
}
|
|
```
|
|
|
|
**Important**: The format string is `"02/01/2006"` (DD/MM/YYYY), NOT `"01/02/2006"` (MM/DD/YYYY).
|
|
|
|
## Integration with Alpine.js Forms
|
|
|
|
The date picker works seamlessly with Alpine.js validation:
|
|
|
|
```templ
|
|
<form x-data="{
|
|
dateIsEmpty: true,
|
|
dateError: '',
|
|
canSubmit: false,
|
|
updateCanSubmit() {
|
|
this.canSubmit = !this.dateIsEmpty;
|
|
}
|
|
}">
|
|
@datepicker.DatePicker(
|
|
"event_date",
|
|
"event_date",
|
|
"Event Date",
|
|
"DD/MM/YYYY",
|
|
true,
|
|
"dateIsEmpty = $el.value === ''; updateCanSubmit();"
|
|
)
|
|
|
|
<!-- Error message -->
|
|
<p x-show="dateError" x-text="dateError"></p>
|
|
|
|
<!-- Submit button -->
|
|
<button x-bind:disabled="!canSubmit">Submit</button>
|
|
</form>
|
|
```
|
|
|
|
## Styling
|
|
|
|
The component uses Tailwind CSS classes and Catppuccin theme colors:
|
|
- `bg-mantle`, `bg-surface0`, `bg-surface1` - backgrounds
|
|
- `border-surface1` - borders
|
|
- `text-subtext0` - muted text
|
|
- `bg-blue` - accent color (today's date)
|
|
- `focus:border-blue` - focus states
|
|
|
|
All styling is built-in; no additional CSS required.
|
|
|
|
## Browser Compatibility
|
|
|
|
Works in all modern browsers that support:
|
|
- Alpine.js 3.x
|
|
- ES6 JavaScript (arrow functions, template literals, etc.)
|
|
- CSS Grid
|
|
|
|
## Examples in Codebase
|
|
|
|
See `internal/view/component/form/new_season.templ` for a real-world usage example.
|