Open
Description

from collections import defaultdict
from dataclasses import dataclass, fields
from types import NoneType
from typing import get_args
from fasthtml.common import *
from monsterui.all import *
hdrs = Theme.blue.headers()
app, rt = fast_app(hdrs=hdrs)
@dataclass
class Profile:
name: str
email: str
age: int|None
def mk_profile_form(errors: dict|None = None):
d = {k:Small(v, style='font-color: red')
for k,v in (errors or {}).items()}
errors = defaultdict(lambda: NotStr(''), d)
return Form(
Fieldset(
Label(
'First name (required)',
Input(name='name'),
errors['name']
),
Label(
'Email (required)',
Input(type='email', name='email'),
errors['email']
),
Label(
'Age',
Input(type='number', name='age'),
errors['age']
)
),
Input(type='submit', value='Subscribe'),
hx_post=update_profile, hx_swap="outerHTML"
)
@rt
def update_profile(profile: Profile):
errors = {}
for field in fields(profile):
value = getattr(profile, field.name)
if not value and NoneType not in get_args(field.type):
errors[field.name] = f'Missing {field.name}'
form = mk_profile_form(errors)
return fill_form(form, profile)
@rt
def index():
return Titled("Form error handling",
mk_profile_form()
)
serve()