plotly / plotly/dash

html.Form() causes page reload when child html.Button() is clicked

Open
#2,510 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

I'm not a html.Form() expert so maybe this is the default behaviour that other users expect for this component, but I think it'd be worth including in the documentation:

Current behaviour:

https://user-images.githubusercontent.com/101562106/233134061-8a29fa53-bc84-4942-bf60-bf04ce30a1f0.mov

  • When developers don't specify any values for target or action, their default ones are _self and the current page/url, respectively (ref: https://www.w3schools.com/html/html_forms_attributes.asp).
  • However, if they are inspected in a callback (using them as Inputs), their official values are None.
  • This can be tested by changing the values in the html.Form component to target='_blank' and action='https://github.com/'. In that case, when users click on the 'send' button, a new tab will be opened with the GitHub website.
  • This behaviour is confusing because typically this type of interactivity in Dash would require explicit coding by the developer.

Expected behaviour

  • Make target and/or action arguments compulsory so developers don't run into this behaviour by accident.
  • Document the default behaviour in the docs: https://dash.plotly.com/dash-html-components/form
  • It doesn't seem possible to disable this behaviour because the disable_n_clicks property (documented) is not valid.

Code to reproduce the issue:

dash==2.9.2

from dash import Dash, html, callback, Input, Output, State, dcc

app = Dash(__name__)

app.layout = html.Div([
    html.Form(
        id='form',
        # target='_blank',
        # action='https://github.com/',
        # method='GET',
        children=[
            dcc.Input(type='text'),
            dcc.Input(type='number'),
            html.Button(children='send')
        ]
    ),
    html.Div(id='out')
])

@callback(
    Output('out', 'children'),
    Input('form', 'method'),
    Input('form', 'target'),
    Input('form', 'action'),
    Input('form', 'role')
)
def t(m, t, a, r) :
    out = f"Method: {m}, Target: {t}, Action: {a}, Role: {r}"
    print(out)
    return out

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided Dash reproduction using html.Form, html.Button, and the form properties as callback Inputs, then compare the observed reload and default values with the form documentation at dash.plotly.com/dash-html-components/form. Done means the intended default or required-argument behavior is decided, the accidental submission behavior is addressed as specified, and the documented form behavior matches the result.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
documentation, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.