Replace LabelSelect with raw Select to fix MonsterUI value bug
MonsterUI LabelSelect has a confirmed bug where it sends the option's
label text instead of the value attribute on form submission. This was
causing 422 validation errors in forms.
- Replace all LabelSelect usages with raw Div(FormLabel, Select) pattern
- Add comments documenting the MonsterUI bug workaround
- Matches pattern already used in feed.py since commit ad1f910
Files modified: eggs.py, move.py, actions.py, products.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,6 @@ from monsterui.all import (
|
||||
ButtonT,
|
||||
FormLabel,
|
||||
LabelInput,
|
||||
LabelSelect,
|
||||
LabelTextArea,
|
||||
)
|
||||
from ulid import ULID
|
||||
@@ -215,19 +214,17 @@ def cohort_form(
|
||||
H2("Create Animal Cohort", cls="text-xl font-bold mb-4"),
|
||||
# Error message if present
|
||||
error_component,
|
||||
# Species dropdown
|
||||
LabelSelect(
|
||||
*species_options,
|
||||
label="Species",
|
||||
id="species",
|
||||
name="species",
|
||||
# Species dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Species", _for="species"),
|
||||
Select(*species_options, name="species", id="species", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Location dropdown
|
||||
LabelSelect(
|
||||
*location_options,
|
||||
label="Location",
|
||||
id="location_id",
|
||||
name="location_id",
|
||||
# Location dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Location", _for="location_id"),
|
||||
Select(*location_options, name="location_id", id="location_id", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Count input
|
||||
LabelInput(
|
||||
@@ -239,26 +236,23 @@ def cohort_form(
|
||||
value=count_value,
|
||||
placeholder="Number of animals",
|
||||
),
|
||||
# Life stage dropdown
|
||||
LabelSelect(
|
||||
*life_stage_options,
|
||||
label="Life Stage",
|
||||
id="life_stage",
|
||||
name="life_stage",
|
||||
# Life stage dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Life Stage", _for="life_stage"),
|
||||
Select(*life_stage_options, name="life_stage", id="life_stage", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Sex dropdown
|
||||
LabelSelect(
|
||||
*sex_options,
|
||||
label="Sex",
|
||||
id="sex",
|
||||
name="sex",
|
||||
# Sex dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Sex", _for="sex"),
|
||||
Select(*sex_options, name="sex", id="sex", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Origin dropdown
|
||||
LabelSelect(
|
||||
*origin_options,
|
||||
label="Origin",
|
||||
id="origin",
|
||||
name="origin",
|
||||
# Origin dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Origin", _for="origin"),
|
||||
Select(*origin_options, name="origin", id="origin", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Optional notes
|
||||
LabelTextArea(
|
||||
@@ -350,19 +344,17 @@ def hatch_form(
|
||||
H2("Record Hatch", cls="text-xl font-bold mb-4"),
|
||||
# Error message if present
|
||||
error_component,
|
||||
# Species dropdown
|
||||
LabelSelect(
|
||||
*species_options,
|
||||
label="Species",
|
||||
id="species",
|
||||
name="species",
|
||||
# Species dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Species", _for="species"),
|
||||
Select(*species_options, name="species", id="species", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Hatch location dropdown
|
||||
LabelSelect(
|
||||
*location_options,
|
||||
label="Hatch Location",
|
||||
id="location_id",
|
||||
name="location_id",
|
||||
# Hatch location dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Hatch Location", _for="location_id"),
|
||||
Select(*location_options, name="location_id", id="location_id", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Hatched count input
|
||||
LabelInput(
|
||||
@@ -374,13 +366,17 @@ def hatch_form(
|
||||
value=hatched_live_value,
|
||||
placeholder="Number hatched",
|
||||
),
|
||||
# Brood location dropdown (optional)
|
||||
# Brood location dropdown (optional) - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
LabelSelect(
|
||||
Div(
|
||||
FormLabel("Brood Location (optional)", _for="assigned_brood_location_id"),
|
||||
Select(
|
||||
*brood_location_options,
|
||||
label="Brood Location (optional)",
|
||||
id="assigned_brood_location_id",
|
||||
name="assigned_brood_location_id",
|
||||
id="assigned_brood_location_id",
|
||||
cls="uk-select",
|
||||
),
|
||||
cls="space-y-2",
|
||||
),
|
||||
P(
|
||||
"If different from hatch location, hatchlings will be placed here",
|
||||
@@ -845,12 +841,11 @@ def tag_end_form(
|
||||
),
|
||||
# Selection container - updated via HTMX when filter changes
|
||||
selection_container,
|
||||
# Tag dropdown
|
||||
LabelSelect(
|
||||
*tag_options,
|
||||
label="Tag to End",
|
||||
id="tag",
|
||||
name="tag",
|
||||
# Tag dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Tag to End", _for="tag"),
|
||||
Select(*tag_options, name="tag", id="tag", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
)
|
||||
if active_tags
|
||||
else Div(
|
||||
@@ -1318,20 +1313,22 @@ def outcome_form(
|
||||
yield_section = Div(
|
||||
H3("Yield Items", cls="text-lg font-semibold mt-4 mb-2"),
|
||||
P("Optional: record products collected from harvest", cls="text-sm text-stone-500 mb-3"),
|
||||
# Using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
LabelSelect(
|
||||
Div(
|
||||
FormLabel("Product", _for="yield_product_code"),
|
||||
Select(
|
||||
*product_options,
|
||||
label="Product",
|
||||
id="yield_product_code",
|
||||
name="yield_product_code",
|
||||
cls="flex-1",
|
||||
id="yield_product_code",
|
||||
cls="uk-select",
|
||||
),
|
||||
LabelSelect(
|
||||
*unit_options,
|
||||
label="Unit",
|
||||
id="yield_unit",
|
||||
name="yield_unit",
|
||||
cls="w-32",
|
||||
cls="space-y-2 flex-1",
|
||||
),
|
||||
Div(
|
||||
FormLabel("Unit", _for="yield_unit"),
|
||||
Select(*unit_options, name="yield_unit", id="yield_unit", cls="uk-select"),
|
||||
cls="space-y-2 w-32",
|
||||
),
|
||||
cls="flex gap-3",
|
||||
),
|
||||
@@ -1377,13 +1374,11 @@ def outcome_form(
|
||||
),
|
||||
# Selection container - updated via HTMX when filter changes
|
||||
selection_container,
|
||||
# Outcome selection
|
||||
LabelSelect(
|
||||
*outcome_options,
|
||||
label="Outcome",
|
||||
id="outcome",
|
||||
name="outcome",
|
||||
required=True,
|
||||
# Outcome selection - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Outcome", _for="outcome"),
|
||||
Select(*outcome_options, name="outcome", id="outcome", cls="uk-select", required=True),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Reason field
|
||||
LabelInput(
|
||||
@@ -1599,13 +1594,13 @@ def status_correct_form(
|
||||
value=filter_str,
|
||||
placeholder="e.g., species:duck location:Coop1",
|
||||
),
|
||||
# New status selection
|
||||
LabelSelect(
|
||||
*status_options,
|
||||
label="New Status",
|
||||
id="new_status",
|
||||
name="new_status",
|
||||
required=True,
|
||||
# New status selection - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("New Status", _for="new_status"),
|
||||
Select(
|
||||
*status_options, name="new_status", id="new_status", cls="uk-select", required=True
|
||||
),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Reason field (required for admin actions)
|
||||
LabelInput(
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from fasthtml.common import H1, H2, A, Div, Form, Hidden, Li, Option, P, Ul
|
||||
from fasthtml.common import H1, H2, A, Div, Form, Hidden, Li, Option, P, Select, Ul
|
||||
from monsterui.all import (
|
||||
Button,
|
||||
ButtonT,
|
||||
FormLabel,
|
||||
LabelInput,
|
||||
LabelSelect,
|
||||
LabelTextArea,
|
||||
TabContainer,
|
||||
)
|
||||
@@ -177,12 +177,11 @@ def harvest_form(
|
||||
H2("Harvest Eggs", cls="text-xl font-bold mb-4"),
|
||||
# Error message if present
|
||||
error_component,
|
||||
# Location dropdown
|
||||
LabelSelect(
|
||||
*location_options,
|
||||
label="Location",
|
||||
id="location_id",
|
||||
name="location_id",
|
||||
# Location dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Location", _for="location_id"),
|
||||
Select(*location_options, name="location_id", id="location_id", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Quantity input (integer only, 0 allowed for "checked but found none")
|
||||
LabelInput(
|
||||
@@ -300,12 +299,11 @@ def sell_form(
|
||||
H2("Sell Products", cls="text-xl font-bold mb-4"),
|
||||
# Error message if present
|
||||
error_component,
|
||||
# Product dropdown
|
||||
LabelSelect(
|
||||
*product_options,
|
||||
label="Product",
|
||||
id="product_code",
|
||||
name="product_code",
|
||||
# Product dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Product", _for="product_code"),
|
||||
Select(*product_options, name="product_code", id="product_code", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Quantity input (integer only, min=1)
|
||||
LabelInput(
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from fasthtml.common import H2, Div, Form, Hidden, Option, P, Span
|
||||
from monsterui.all import Alert, AlertT, Button, ButtonT, LabelInput, LabelSelect, LabelTextArea
|
||||
from fasthtml.common import H2, Div, Form, Hidden, Option, P, Select, Span
|
||||
from monsterui.all import Alert, AlertT, Button, ButtonT, FormLabel, LabelInput, LabelTextArea
|
||||
from ulid import ULID
|
||||
|
||||
from animaltrack.models.events import Event
|
||||
@@ -151,12 +151,11 @@ def move_form(
|
||||
),
|
||||
# Selection container - updated via HTMX when filter changes
|
||||
selection_container,
|
||||
# Destination dropdown
|
||||
LabelSelect(
|
||||
*location_options,
|
||||
label="Destination",
|
||||
id="to_location_id",
|
||||
name="to_location_id",
|
||||
# Destination dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Destination", _for="to_location_id"),
|
||||
Select(*location_options, name="to_location_id", id="to_location_id", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Optional notes
|
||||
LabelTextArea(
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from fasthtml.common import H2, Form, Hidden, Option
|
||||
from monsterui.all import Button, ButtonT, LabelInput, LabelSelect, LabelTextArea
|
||||
from fasthtml.common import H2, Div, Form, Hidden, Option, P, Select
|
||||
from monsterui.all import Button, ButtonT, FormLabel, LabelInput, LabelTextArea
|
||||
from ulid import ULID
|
||||
|
||||
from animaltrack.models.reference import Product
|
||||
@@ -47,8 +47,6 @@ def product_sold_form(
|
||||
# Error display component
|
||||
error_component = None
|
||||
if error:
|
||||
from fasthtml.common import Div, P
|
||||
|
||||
error_component = Div(
|
||||
P(error, cls="text-red-500 text-sm"),
|
||||
cls="mb-4",
|
||||
@@ -58,12 +56,11 @@ def product_sold_form(
|
||||
H2("Record Sale", cls="text-xl font-bold mb-4"),
|
||||
# Error message if present
|
||||
error_component,
|
||||
# Product dropdown
|
||||
LabelSelect(
|
||||
*product_options,
|
||||
label="Product",
|
||||
id="product_code",
|
||||
name="product_code",
|
||||
# Product dropdown - using raw Select due to MonsterUI LabelSelect value bug
|
||||
Div(
|
||||
FormLabel("Product", _for="product_code"),
|
||||
Select(*product_options, name="product_code", id="product_code", cls="uk-select"),
|
||||
cls="space-y-2",
|
||||
),
|
||||
# Quantity input (integer only, min=1)
|
||||
LabelInput(
|
||||
|
||||
Reference in New Issue
Block a user