Extract DateTime picker to static JS file
Moves ~50 lines of inline JavaScript from event_datetime_field() to a static file. The component now uses data attributes for element binding and global functions (toggleDatetimePicker, updateDatetimeTs) from the static JS file. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
53
src/animaltrack/static/v1/datetime-picker.js
Normal file
53
src/animaltrack/static/v1/datetime-picker.js
Normal file
@@ -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="<field_id>"
|
||||||
|
* - Picker container: data-datetime-picker="<field_id>"
|
||||||
|
* - Input element: data-datetime-input="<field_id>"
|
||||||
|
* - Hidden ts_utc field: data-datetime-ts="<field_id>"
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from typing import Any
|
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 (
|
from monsterui.all import (
|
||||||
Alert,
|
Alert,
|
||||||
AlertT,
|
AlertT,
|
||||||
@@ -142,43 +142,14 @@ def event_datetime_field(
|
|||||||
Returns:
|
Returns:
|
||||||
Div containing the datetime picker with toggle functionality.
|
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
|
# If initial value is set, start with picker expanded
|
||||||
has_initial = bool(initial_value)
|
has_initial = bool(initial_value)
|
||||||
picker_style = "display: block;" if has_initial else "display: none;"
|
picker_style = "display: block;" if has_initial else "display: none;"
|
||||||
toggle_text = "Use current time" if has_initial else "Set custom date"
|
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(
|
return Div(
|
||||||
|
# Load static JS for datetime picker functionality
|
||||||
|
Script(src="/static/v1/datetime-picker.js"),
|
||||||
FormLabel("Event Time"),
|
FormLabel("Event Time"),
|
||||||
Div(
|
Div(
|
||||||
P(
|
P(
|
||||||
@@ -187,29 +158,30 @@ def event_datetime_field(
|
|||||||
Span(
|
Span(
|
||||||
toggle_text,
|
toggle_text,
|
||||||
cls="text-blue-400 hover:text-blue-300 cursor-pointer underline",
|
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",
|
cls="text-sm",
|
||||||
),
|
),
|
||||||
Div(
|
Div(
|
||||||
Input(
|
Input(
|
||||||
id=input_id,
|
|
||||||
name=f"{field_id}_value",
|
name=f"{field_id}_value",
|
||||||
type="datetime-local",
|
type="datetime-local",
|
||||||
value=initial_value,
|
value=initial_value,
|
||||||
cls="uk-input w-full mt-2",
|
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(
|
P(
|
||||||
"Select date/time for this event (leave empty for current time)",
|
"Select date/time for this event (leave empty for current time)",
|
||||||
cls="text-xs text-stone-500 mt-1",
|
cls="text-xs text-stone-500 mt-1",
|
||||||
),
|
),
|
||||||
id=picker_id,
|
data_datetime_picker=field_id,
|
||||||
style=picker_style,
|
style=picker_style,
|
||||||
),
|
),
|
||||||
cls="mt-1",
|
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",
|
cls="space-y-1",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user