diff --git a/src/animaltrack/static/v1/datetime-picker.js b/src/animaltrack/static/v1/datetime-picker.js new file mode 100644 index 0000000..7257dfd --- /dev/null +++ b/src/animaltrack/static/v1/datetime-picker.js @@ -0,0 +1,53 @@ +/** + * Datetime Picker Component + * + * Provides toggle and conversion functionality for backdating events. + * Uses data attributes to identify related elements. + * + * Expected HTML structure: + * - Toggle element: data-datetime-toggle="" + * - Picker container: data-datetime-picker="" + * - Input element: data-datetime-input="" + * - Hidden ts_utc field: data-datetime-ts="" + */ + +/** + * Toggle the datetime picker visibility. + * @param {string} fieldId - The unique field ID prefix. + */ +function toggleDatetimePicker(fieldId) { + var picker = document.querySelector('[data-datetime-picker="' + fieldId + '"]'); + var input = document.querySelector('[data-datetime-input="' + fieldId + '"]'); + var tsField = document.querySelector('[data-datetime-ts="' + fieldId + '"]'); + var toggle = document.querySelector('[data-datetime-toggle="' + fieldId + '"]'); + + if (!picker || !toggle) return; + + if (picker.style.display === 'none') { + picker.style.display = 'block'; + toggle.textContent = 'Use current time'; + } else { + picker.style.display = 'none'; + toggle.textContent = 'Set custom date'; + if (input) input.value = ''; + if (tsField) tsField.value = '0'; + } +} + +/** + * Update the hidden ts_utc field when datetime input changes. + * @param {string} fieldId - The unique field ID prefix. + */ +function updateDatetimeTs(fieldId) { + var input = document.querySelector('[data-datetime-input="' + fieldId + '"]'); + var tsField = document.querySelector('[data-datetime-ts="' + fieldId + '"]'); + + if (!tsField) return; + + if (input && input.value) { + var date = new Date(input.value); + tsField.value = date.getTime().toString(); + } else { + tsField.value = '0'; + } +} diff --git a/src/animaltrack/web/templates/actions.py b/src/animaltrack/web/templates/actions.py index 38890bd..47dbfb7 100644 --- a/src/animaltrack/web/templates/actions.py +++ b/src/animaltrack/web/templates/actions.py @@ -4,7 +4,7 @@ from collections.abc import Callable from typing import Any -from fasthtml.common import H2, H3, Div, Form, Hidden, Input, Option, P, Select, Span +from fasthtml.common import H2, H3, Div, Form, Hidden, Input, Option, P, Script, Select, Span from monsterui.all import ( Alert, AlertT, @@ -142,43 +142,14 @@ def event_datetime_field( Returns: Div containing the datetime picker with toggle functionality. """ - picker_id = f"{field_id}_picker" - input_id = f"{field_id}_input" - ts_utc_id = f"{field_id}_ts_utc" - # 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" - # Inline JavaScript for toggle click handler - toggle_onclick = f""" - var picker = document.getElementById('{picker_id}'); - var input = document.getElementById('{input_id}'); - var tsField = document.getElementById('{ts_utc_id}'); - if (picker.style.display === 'none') {{ - picker.style.display = 'block'; - this.textContent = 'Use current time'; - }} else {{ - picker.style.display = 'none'; - this.textContent = 'Set custom date'; - input.value = ''; - if (tsField) tsField.value = '0'; - }} - """ - - # Inline JavaScript for input change handler - input_onchange = f""" - var tsField = document.getElementById('{ts_utc_id}'); - if (tsField && this.value) {{ - var date = new Date(this.value); - tsField.value = date.getTime().toString(); - }} else if (tsField) {{ - tsField.value = '0'; - }} - """ - return Div( + # Load static JS for datetime picker functionality + Script(src="/static/v1/datetime-picker.js"), FormLabel("Event Time"), Div( P( @@ -187,29 +158,30 @@ def event_datetime_field( Span( toggle_text, cls="text-blue-400 hover:text-blue-300 cursor-pointer underline", - hx_on_click=toggle_onclick, + data_datetime_toggle=field_id, + hx_on_click=f"toggleDatetimePicker('{field_id}')", ), cls="text-sm", ), Div( Input( - id=input_id, name=f"{field_id}_value", type="datetime-local", value=initial_value, cls="uk-input w-full mt-2", - hx_on_change=input_onchange, + data_datetime_input=field_id, + hx_on_change=f"updateDatetimeTs('{field_id}')", ), P( "Select date/time for this event (leave empty for current time)", cls="text-xs text-stone-500 mt-1", ), - id=picker_id, + data_datetime_picker=field_id, style=picker_style, ), cls="mt-1", ), - Hidden(id=ts_utc_id, name="ts_utc", value=initial_ts), + Hidden(name="ts_utc", value=initial_ts, data_datetime_ts=field_id), cls="space-y-1", )