plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
21.16k stars 2.04k forks source link

Callback does not update dcc.Dropdown's style "display" property #1358

Open AmirAlavi opened 4 years ago

AmirAlavi commented 4 years ago

Describe your context Please provide us your environment so we can easily reproduce the issue.

Describe the bug I am trying to have a dropdown show/hide based on the value of a radio item. My initial attempt used a callback to update the dropdown's style with either {"display": "block"} or {"display": "none"}. While the dropdown would appear/disappear correctly, the dropdown's little upside triangle icon was not showing. It's a vital visual cue to the user that it's a dropdown and not an input box.

Video recording with {"display": "block"}: Icon bug

Some searching for solutions led me to a similar issue with a solution on the forums, to instead use {"display": "block !important"}.

While this brought back the little triangle icon, now the appear/disappear is broken. Selecting "show" in the radio item no longer brings back the dropdown from hidden state. Using "inspect element" on any broswer I've tested, I do not observe a change of the tag's display property.

Video recording with {"display": "block !important"}: Show bug

Expected behavior

I would expect that using {"display": "block"} on a dcc.Dropdown would correctly show the triangle icon. I would expect that using {"display": "block !important"} would cause the hidden dropdown to reappear.

Minimum working example

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State

HIDE_STY = {"display": "none"}
SHOW_STY = {"display": "block"}
SHOW_STY_IMP = {"display": "block !important"}

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Dropdown(
            id="drop-select",
            options=[
                {"label": "foo", "value": "foo"},
                {"label": "bar", "value": "bar"},
            ],
            value="foo",
        ),
        dcc.RadioItems(
            id="radio-select",
            options=[
                {"label": "show", "value": "show"},
                {"label": "hide", "value": "hide"},
            ],
            value="show",
        ),
    ]
)

@app.callback(Output("drop-select", "style"), [Input("radio-select", "value")])
def update_dropdown_visibility(value):
    if value == "show":
        # ---> Both of these seem problematic <---
        return SHOW_STY
        # return SHOW_STY_IMP
    else:
        return HIDE_STY

if __name__ == "__main__":
    app.run_server(debug=True)
MarcosSbarbati commented 3 years ago

Having the same issue here.

MarcosSbarbati commented 3 years ago

The momentary solution I found is to make an ID inside the Div and direct the output straight as a dropdown into the Div.