From 1a0f87152fde34f1b838ede3a4e248f19d71593c Mon Sep 17 00:00:00 2001 From: Ruben Date: Wed, 24 Jan 2024 12:32:13 -0800 Subject: [PATCH 1/2] feat(FormField): accept className --- src/python-fastui/fastui/json_schema.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python-fastui/fastui/json_schema.py b/src/python-fastui/fastui/json_schema.py index 6bd68754..74655582 100644 --- a/src/python-fastui/fastui/json_schema.py +++ b/src/python-fastui/fastui/json_schema.py @@ -175,6 +175,7 @@ def json_schema_field_to_field( initial=schema.get('default'), description=schema.get('description'), mode=schema.get('mode', 'checkbox'), + class_name=schema.get('className'), ) elif field := special_string_field(schema, name, title, required, False): return field @@ -182,10 +183,12 @@ def json_schema_field_to_field( return FormFieldInput( name=name, title=title, + placeholder=schema.get('placeholder'), html_type=input_html_type(schema), required=required, initial=schema.get('default'), description=schema.get('description'), + class_name=schema.get('className'), ) @@ -235,6 +238,7 @@ def special_string_field( multiple=multiple, accept=schema.get('accept'), description=schema.get('description'), + class_name=schema.get('className'), ) elif enum := schema.get('enum'): enum_labels = schema.get('enum_labels', {}) @@ -247,6 +251,7 @@ def special_string_field( options=[SelectOption(value=v, label=enum_labels.get(v) or as_title(v)) for v in enum], initial=schema.get('default'), description=schema.get('description'), + class_name=schema.get('className'), ) elif search_url := schema.get('search_url'): return FormFieldSelectSearch( @@ -258,6 +263,7 @@ def special_string_field( multiple=multiple, initial=schema.get('initial'), description=schema.get('description'), + class_name=schema.get('className'), ) From ed8f947b659b58d9624bde3a2faca334b1ebbf53 Mon Sep 17 00:00:00 2001 From: Ruben Date: Mon, 19 Feb 2024 21:10:43 +0100 Subject: [PATCH 2/2] tests --- src/python-fastui/tests/test_forms.py | 98 ++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/src/python-fastui/tests/test_forms.py b/src/python-fastui/tests/test_forms.py index b0919fad..c0f1b528 100644 --- a/src/python-fastui/tests/test_forms.py +++ b/src/python-fastui/tests/test_forms.py @@ -6,7 +6,7 @@ from fastapi import HTTPException from fastui import components from fastui.forms import FormFile, Textarea, fastui_form -from pydantic import BaseModel +from pydantic import BaseModel, Field from starlette.datastructures import FormData, Headers, UploadFile from typing_extensions import Annotated @@ -469,3 +469,99 @@ def test_form_textarea_form_fields(): } ], } + + +class FormWithCustomClassNameField(BaseModel): + name: str + size: int = 4 + internal_id: int = Field( + title='Internal id', + json_schema_extra={ + 'className': 'visually-hidden', + }, + ) + + +def test_fields_with_custom_class_name(): + m = components.ModelForm(model=FormWithCustomClassNameField, submit_url='/foobar/') + + assert m.model_dump(by_alias=True, exclude_none=True) == { + 'submitUrl': '/foobar/', + 'method': 'POST', + 'type': 'ModelForm', + 'formFields': [ + { + 'name': 'name', + 'title': ['Name'], + 'required': True, + 'locked': False, + 'htmlType': 'text', + 'type': 'FormFieldInput', + }, + { + 'name': 'size', + 'title': ['Size'], + 'initial': 4, + 'required': False, + 'locked': False, + 'htmlType': 'number', + 'type': 'FormFieldInput', + }, + { + 'className': 'visually-hidden', + 'htmlType': 'number', + 'locked': False, + 'name': 'internal_id', + 'required': True, + 'title': ['Internal id'], + 'type': 'FormFieldInput', + }, + ], + } + + +class FormWithPlaceholderField(BaseModel): + name: str + size: int = 4 + internal_id: int = Field( + title='Internal id', + json_schema_extra={'placeholder': '1234'}, + ) + + +def test_fields_with_placeholder_values(): + m = components.ModelForm(model=FormWithPlaceholderField, submit_url='/foobar/') + + assert m.model_dump(by_alias=True, exclude_none=True) == { + 'submitUrl': '/foobar/', + 'method': 'POST', + 'type': 'ModelForm', + 'formFields': [ + { + 'name': 'name', + 'title': ['Name'], + 'required': True, + 'locked': False, + 'htmlType': 'text', + 'type': 'FormFieldInput', + }, + { + 'name': 'size', + 'title': ['Size'], + 'initial': 4, + 'required': False, + 'locked': False, + 'htmlType': 'number', + 'type': 'FormFieldInput', + }, + { + 'htmlType': 'number', + 'locked': False, + 'name': 'internal_id', + 'placeholder': '1234', + 'required': True, + 'title': ['Internal id'], + 'type': 'FormFieldInput', + }, + ], + }