From bb597cf7d6683ead2573a70ca08fdbccd864cdb4 Mon Sep 17 00:00:00 2001 From: Masen Furer Date: Wed, 23 Oct 2024 14:50:57 -0700 Subject: [PATCH] Handle named form controls similarly to ID'd form controls --- reflex/.templates/web/utils/state.js | 26 ++++++++++++++----------- reflex/components/el/elements/forms.py | 8 ++++++-- reflex/components/el/elements/forms.pyi | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/reflex/.templates/web/utils/state.js b/reflex/.templates/web/utils/state.js index 24092f235..d4f7b5df4 100644 --- a/reflex/.templates/web/utils/state.js +++ b/reflex/.templates/web/utils/state.js @@ -860,23 +860,27 @@ export const getRefValue = (ref) => { if (!ref || !ref.current) { return; } - if (ref.current.type == "checkbox") { - return ref.current.checked; // chakra + return getElementValue(ref.current) +} + +export const getElementValue = (el) => { + if (el.type == "checkbox") { + return el.checked; // chakra } else if ( - ref.current.className?.includes("rt-CheckboxRoot") || - ref.current.className?.includes("rt-SwitchRoot") + el.className?.includes("rt-CheckboxRoot") || + el.className?.includes("rt-SwitchRoot") ) { - return ref.current.ariaChecked == "true"; // radix - } else if (ref.current.className?.includes("rt-SliderRoot")) { + return el.ariaChecked == "true"; // radix + } else if (el.className?.includes("rt-SliderRoot")) { // find the actual slider - return ref.current.querySelector(".rt-SliderThumb")?.ariaValueNow; + return el.querySelector(".rt-SliderThumb")?.ariaValueNow; } else { //querySelector(":checked") is needed to get value from radio_group return ( - ref.current.value || - (ref.current.querySelector && - ref.current.querySelector(":checked") && - ref.current.querySelector(":checked")?.value) + el.value || + (el.querySelector && + el.querySelector(":checked") && + el.querySelector(":checked")?.value) ); } }; diff --git a/reflex/components/el/elements/forms.py b/reflex/components/el/elements/forms.py index a343991d5..b40a6216f 100644 --- a/reflex/components/el/elements/forms.py +++ b/reflex/components/el/elements/forms.py @@ -29,7 +29,11 @@ HANDLE_SUBMIT_JS_JINJA2 = Environment().from_string( const handleSubmit_{{ handle_submit_unique_name }} = useCallback((ev) => { const $form = ev.target ev.preventDefault() - const {{ form_data }} = {...Object.fromEntries(new FormData($form).entries()), ...{{ field_ref_mapping }}}; + const {{ form_data }} = { + ...Object.fromEntries(new FormData($form).entries()), + ...{{ field_ref_mapping }}, + ...Object.fromEntries(Array.from($form.children).filter(el => el.name).map(el => [el.name, getElementValue(el)])), + }; ({{ on_submit_event_chain }}()); @@ -187,7 +191,7 @@ class Form(BaseHTML): """ return { "react": "useCallback", - f"/{Dirs.STATE_PATH}": ["getRefValue", "getRefValues"], + f"/{Dirs.STATE_PATH}": ["getRefValue", "getRefValues", "getElementValue"], } def add_hooks(self) -> list[str]: diff --git a/reflex/components/el/elements/forms.pyi b/reflex/components/el/elements/forms.pyi index 135291213..da3c250c4 100644 --- a/reflex/components/el/elements/forms.pyi +++ b/reflex/components/el/elements/forms.pyi @@ -17,7 +17,7 @@ from .base import BaseHTML FORM_DATA = Var(_js_expr="form_data") HANDLE_SUBMIT_JS_JINJA2 = Environment().from_string( - "\n const handleSubmit_{{ handle_submit_unique_name }} = useCallback((ev) => {\n const $form = ev.target\n ev.preventDefault()\n const {{ form_data }} = {...Object.fromEntries(new FormData($form).entries()), ...{{ field_ref_mapping }}};\n\n ({{ on_submit_event_chain }}());\n\n if ({{ reset_on_submit }}) {\n $form.reset()\n }\n })\n " + "\n const handleSubmit_{{ handle_submit_unique_name }} = useCallback((ev) => {\n const $form = ev.target\n ev.preventDefault()\n const {{ form_data }} = {\n ...Object.fromEntries(new FormData($form).entries()),\n ...{{ field_ref_mapping }},\n ...Object.fromEntries(Array.from($form.children).filter(el => el.name).map(el => [el.name, getElementValue(el)])),\n };\n\n ({{ on_submit_event_chain }}());\n\n if ({{ reset_on_submit }}) {\n $form.reset()\n }\n })\n " ) class Button(BaseHTML):