0

I'm trying to build a small form with dash and dash-bootstrap-components, but I can't figure out how to use the 'action' attribute of the form.

Or, rather, I'm trying to save the data that the user inputs into the form to the Postgres DB, and the action attribute seems to be the way to do that, but I wasn't able to find any examples on how to use it.

Did anybody have experience building forms with DBC?

EDIT my current solution is (in a simplified form):

def handle_submit(n_submit, e, pass): 
    username = e.split('@') 
    pg = pd.DataFrame(e, username, pass) 
    if n_submit:
       pg.to_sql("table", con=db.engine, if_exists="append", index=False)
       return 'success'

but that doesn't seem to work.

Denis Shvetsov
  • 206
  • 1
  • 2
  • 10

1 Answers1

2

By default the action endpoint isn't used

prevent_default_on_submit (boolean; default True): The form calls preventDefault on submit events. If you want form data to be posted to the endpoint specified by action on submit events, set prevent_default_on_submit to False. Defaults to True.

Based on your question it seems you just want to do something on submit and have no need for the action. In this case you can do something like this:

from dash import Dash
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Output, Input, State

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

form = dbc.Form(
    id="form",
    children=[
        dbc.FormGroup(
            [
                dbc.Label("Email", className="mr-2"),
                dbc.Input(id="email", type="email", placeholder="Enter email"),
            ],
            className="mr-3",
        ),
        dbc.FormGroup(
            [
                dbc.Label("Password", className="mr-2"),
                dbc.Input(id="password", type="password", placeholder="Enter password"),
            ],
            className="mr-3",
        ),
        dbc.Button("Submit", color="primary"),
    ],
    inline=True,
)

app.layout = html.Div([form, html.Div(id="output")])


@app.callback(
    Output("output", "children"),
    Input("form", "n_submit"),
    State("email", "value"),
    State("password", "value"),
    prevent_initial_call=True
)
def handle_submit(n_submit, email, password):
    # Do stuff...
    return n_submit


if __name__ == "__main__":
    app.run_server()

n_submit is returned in the callback above in order to show that the submit action works, but you probably want to change this to something else according to your needs.

Update

Based on your edit you could change the callback to something like this:

@app.callback(
    Output("output", "children"),
    Input("form", "n_submit"),
    State("email", "value"),
    State("password", "value"),
    prevent_initial_call=True,
)
def handle_submit(n_submit, email, password):
    username = email.split("@")
    pg = pd.DataFrame(
        {"email": [email], "username": [username], "password": [password]}
    )
    if n_submit:
        pg.to_sql("table", con=db.engine, if_exists="append", index=False)
        return "success"
    return ""

I've changed the way the DataFrame is constructed and the variable names. pass is a reserved keyword so I wouldn't use that as a parameter name. I've also added a default return statement. Not really necessary here as prevent_initial_call is set to True, but it shows how you could account for the case that n_submit were to evaluate to False.

5eb
  • 14,798
  • 5
  • 21
  • 65
  • Bas, thank you for your input. Can you please do me a favor and complete your example so that the function would take the values from the input fields and save them to a database? Right now I have something like: ```def handle_submit(n_submit, e, pass): username = e.split('@') pg = pd.DataFrame(e, username, pass) if n_submit: pg.to_sql("table", con=db.engine, if_exists="append", index=False) return 'success'``` but that doesn't seem to work. – Denis Shvetsov Jul 11 '21 at 21:54
  • I added this piece of code into the body of the problem under `EDIT` for better visibility – Denis Shvetsov Jul 11 '21 at 21:57
  • thank you again very much. I managed to solve my issue with your advice. – Denis Shvetsov Jul 13 '21 at 10:48