fix: preserve datetime picker value when form validation fails

The event_datetime_field component now accepts initial_value and
initial_ts parameters. When re-rendering a form after validation
error, the datetime picker value is preserved and shown expanded.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-01 13:36:07 +00:00
parent 680227f53f
commit b74ca53f20
2 changed files with 25 additions and 5 deletions

View File

@@ -230,6 +230,10 @@ def _render_cohort_error(
selected_sex=form_data.get("sex", "unknown") if form_data else "",
selected_origin=form_data.get("origin", "") if form_data else "",
count_value=form_data.get("count", "") if form_data else "",
datetime_value=(
form_data.get("cohort_datetime_value", "") if form_data else ""
),
datetime_ts=form_data.get("ts_utc", "0") if form_data else "0",
),
title="Create Cohort - AnimalTrack",
active_nav=None,

View File

@@ -26,7 +26,11 @@ from animaltrack.selection.validation import SelectionDiff
# =============================================================================
def event_datetime_field(field_id: str = "event_datetime") -> Div:
def event_datetime_field(
field_id: str = "event_datetime",
initial_value: str = "",
initial_ts: str = "0",
) -> Div:
"""Create a collapsible datetime picker for backdating events.
When collapsed, shows "Now" and the event will use the current time.
@@ -35,6 +39,8 @@ def event_datetime_field(field_id: str = "event_datetime") -> Div:
Args:
field_id: Unique ID prefix for the datetime field elements.
initial_value: Initial value for the datetime-local input (for form preservation).
initial_ts: Initial value for the hidden ts_utc field (for form preservation).
Returns:
Div containing the datetime picker with toggle functionality.
@@ -43,6 +49,11 @@ def event_datetime_field(field_id: str = "event_datetime") -> Div:
picker_id = f"{field_id}_picker"
input_id = f"{field_id}_input"
# If initial value is set, start with picker expanded
has_initial = bool(initial_value)
picker_style = "display: block;" if has_initial else "display: none;"
toggle_text = "Use current time" if has_initial else "Set custom date"
# JavaScript for toggle and conversion
script = f"""
(function() {{
@@ -84,7 +95,7 @@ def event_datetime_field(field_id: str = "event_datetime") -> Div:
Span("Now", cls="text-stone-400"),
" - ",
Span(
"Set custom date",
toggle_text,
id=toggle_id,
cls="text-blue-400 hover:text-blue-300 cursor-pointer underline",
),
@@ -95,6 +106,7 @@ def event_datetime_field(field_id: str = "event_datetime") -> Div:
id=input_id,
name=f"{field_id}_value",
type="datetime-local",
value=initial_value,
cls="uk-input w-full mt-2",
),
P(
@@ -102,11 +114,11 @@ def event_datetime_field(field_id: str = "event_datetime") -> Div:
cls="text-xs text-stone-500 mt-1",
),
id=picker_id,
style="display: none;",
style=picker_style,
),
cls="mt-1",
),
Hidden(name="ts_utc", value="0"),
Hidden(name="ts_utc", value=initial_ts),
Script(script),
cls="space-y-1",
)
@@ -127,6 +139,8 @@ def cohort_form(
selected_sex: str = "unknown",
selected_origin: str = "",
count_value: str = "",
datetime_value: str = "",
datetime_ts: str = "0",
action: Callable[..., Any] | str = "/actions/animal-cohort",
) -> Form:
"""Create the Cohort Creation form.
@@ -141,6 +155,8 @@ def cohort_form(
selected_sex: Pre-selected sex.
selected_origin: Pre-selected origin.
count_value: Pre-filled count value.
datetime_value: Pre-filled datetime-local input value.
datetime_ts: Pre-filled ts_utc hidden field value.
action: Route function or URL string for form submission.
Returns:
@@ -253,7 +269,7 @@ def cohort_form(
name="origin",
),
# Event datetime picker (for backdating)
event_datetime_field("cohort_datetime"),
event_datetime_field("cohort_datetime", datetime_value, datetime_ts),
# Hidden nonce for idempotency
Hidden(name="nonce", value=str(ULID())),
# Submit button