reflex
reflex copied to clipboard
form.submit() fails if using dialog.close()
Describe the bug form.submit() fails if using dialog.close()
To Reproduce
import reflex as rx
class FormState(rx.State):
form_data: dict = {}
def handle_submit(self, form_data: dict):
"""Handle the form submit."""
self.form_data = form_data
app = rx.App()
@rx.page()
def index():
return rx.dialog.root(
rx.dialog.trigger(
rx.button(
rx.icon("plus", size=26),
rx.text("Test Form in Dialog", size="4", display=["none", "none", "block"]),
size="3",
),
),
rx.dialog.content(
rx.dialog.title(
"Simple Form",
weight="bold",
margin="0",
),
rx.form.root(
rx.form.field(
rx.flex(
rx.form.label("Email"),
rx.form.control(
rx.input(
placeholder="Email Address",
# type attribute is required for "typeMismatch" validation
type="email",
),
as_child=True,
),
rx.form.message(
"Please enter a valid email",
match="typeMismatch",
),
rx.flex(
rx.dialog.close(
rx.button(
"Cancel",
variant="soft",
color_scheme="gray",
),
),
rx.form.submit(
rx.dialog.close(
rx.button("Submit And Close"), # Form submission cancelled
),
as_child=True,
),
rx.form.submit(
rx.button("Submit Without Closing"), # Works as expected
as_child=True,
),
padding_top="2em",
spacing="3",
mt="4",
justify="end",
),
direction="column",
spacing="2",
align="stretch",
),
name="email",
),
on_submit=FormState.handle_submit,
reset_on_submit=True,
),
max_width="450px",
padding="1.5em",
border=f"2px solid {rx.color('accent', 7)}",
border_radius="25px",
),
)
Expected behavior
The above is taken from one of the standard templates, I get a console error Form submission canceled because the form is not connected
I couldn't find a workaround.
Specifics (please complete the following information):
- Python Version: 3.12.3
- Reflex Version: 0.6.1+
I tried to reproduce this issue and it actually appears to be working as intended on my end.
Tried with v0.6.1 and with current main. In both cases, if I entered a valid email address, then the form submit handler was called.
I did notice a bit of weirdness: when i enter an invalid email, the form validation fails, which blocks the submit... but the dialog still closes, so the user isn't really aware that there was a validation error, it just seems like nothing happened.
To work around this, you might need to use a flag in the FormState like dialog_is_open: bool, and have the dialog controlled via that state var; then instead of relying on rx.dialog.close, you can just flip the flag in the on_submit handler after everything goes through.
Some sample code:
import reflex as rx
class FormState(rx.State):
form_data: dict = {}
dialog_is_open: bool = False
stay_open_after_submit: bool = False
def handle_submit(self, form_data: dict):
"""Handle the form submit."""
self.form_data = form_data
if not self.stay_open_after_submit:
self.dialog_is_open = False
app = rx.App()
@rx.page()
def index():
return rx.dialog.root(
rx.dialog.trigger(
rx.button(
rx.icon("plus", size=26),
rx.text("Test Form in Dialog", size="4", display=["none", "none", "block"]),
size="3",
),
),
rx.dialog.content(
rx.dialog.title(
"Simple Form",
weight="bold",
margin="0",
),
rx.form.root(
rx.form.field(
rx.flex(
rx.form.label("Email"),
rx.form.control(
rx.input(
placeholder="Email Address",
# type attribute is required for "typeMismatch" validation
type="email",
),
as_child=True,
),
rx.form.message(
"Please enter a valid email",
match="typeMismatch",
),
rx.flex(
rx.dialog.close(
rx.button(
"Cancel",
variant="soft",
color_scheme="gray",
),
),
rx.spacer(),
rx.text("Keep Open?"),
rx.switch(
checked=FormState.stay_open_after_submit,
on_change=FormState.set_stay_open_after_submit,
),
rx.form.submit(
rx.button("Submit"),
as_child=True,
),
align="center",
padding_top="2em",
spacing="3",
mt="4",
justify="end",
),
direction="column",
spacing="2",
align="stretch",
),
name="email",
),
on_submit=FormState.handle_submit,
reset_on_submit=True,
),
max_width="450px",
padding="1.5em",
border=f"2px solid {rx.color('accent', 7)}",
border_radius="25px",
),
open=FormState.dialog_is_open,
on_open_change=FormState.set_dialog_is_open,
), rx.text(FormState.form_data.to_string())
Thank you, I was indeed using valid email addresses, in fact any type of field shows the same behaviour here
Is the following inverse nesting valid? It doesn't work for me either but I don't see the same console error.
rx.dialog.close(
rx.form.submit(
rx.button("Submit And Close"), # Form submission cancelled
as_child=True,
),
),
I have now been able to test with a different browser and confirmed the issue occurs in Edge (103.0.1264.77) but not in Firefox (115.12.0esr)
This issue is now happening for me on Firefox too
Any news on this? I have the same issue with latest Reflex in both Vivaldi and Firefox. Even the example from the docs is not working for me.
It's still not working on Firefox. "rx.dialog.close" seems blocking the trigger of form submission.
The last form's on_submit in https://reflex.dev/docs/getting-started/dashboard-tutorial/ is not called.