Using forms as State or Input in a dash.callback works fine. Using it as Output does not work. The layout will be rendered just fine but no callback works and I see a "Overlapping wildcard callback outputs" error in the browser logs.
Below is an example. The second callback causes the bug. If I remove it the other callback will work again. I also tried a allow_duplicate=True which also did not work.
I realized that there is no example in any tutorial where form data is used as Output. So probably it's rather a feature request than a bug report.
import dash_mantine_components as dmc
import dash
from dash import Input, Output, State, callback, html
from dash_pydantic_form import ModelForm
from pydantic import BaseModel, Field, ValidationError
email_regex = r"^\S+@\S+\.\S+$"
class LoginData(BaseModel):
email: str = Field(
title="Email",
description="Work email only, no gmail allowed",
pattern=email_regex,
)
password: str = Field(title="Password", description="Make it strong", min_length=6)
stack = dmc.Stack(
[
ModelForm(LoginData, "login", "auto", submit_on_enter=True),
html.Div(dmc.Button("Submit", id="submit", mt=-10)),
html.Div(dmc.Button("Prefill", id="prefill", mt=-10)),
html.Div(id="output"),
]
)
@callback(
Output("output", "children"),
Output(ModelForm.ids.errors("login", "auto"), "data"),
Input("submit", "n_clicks"),
Input(ModelForm.ids.form("login", "auto"), "data-submit"),
State(ModelForm.ids.main("login", "auto"), "data"),
prevent_initial_call=True,
)
def check_form(_trigger: int, _trigger2: int, form_data: dict):
try:
LoginData.model_validate(form_data)
except ValidationError as exc:
errors = {":".join([str(x) for x in error["loc"]]): error["msg"] for error in exc.errors()}
return dmc.Text("Try again", fw=500, c="red"), errors
return dmc.Text("Form is valid", c="green"), {}
@callback(
Output(ModelForm.ids.main("login", "auto"), "data"),
Input("prefill", "n_clicks"),
prevent_initial_call=True,
)
def prefill(_trigger: int):
return LoginData(email="foo@mail.com", password="abcabc").model_dump()
dash._dash_renderer._set_react_version('18.2.0')
app = dash.Dash(__name__, external_stylesheets=dmc.styles.ALL)
app.layout = dmc.MantineProvider(stack)
if __name__ == '__main__':
app.run_server()
As you say this is not currently supported. An easy workaround however is to target the parent of the form in the callback and replace it with a new one.
Using forms as
State
orInput
in adash.callback
works fine. Using it asOutput
does not work. The layout will be rendered just fine but no callback works and I see a"Overlapping wildcard callback outputs"
error in the browser logs.Below is an example. The second callback causes the bug. If I remove it the other callback will work again. I also tried a
allow_duplicate=True
which also did not work.I realized that there is no example in any tutorial where form data is used as
Output
. So probably it's rather a feature request than a bug report.