Black Lives Matter. Please consider donating to Black Girls Code today.

Dash Dropdown visibility bug with callback

Hello,

I’ve been working on an app recently using Dash. The app uses a number of controls, for example Input and Dropdown from the core components. One feature I wanted to include was that only one of the Input or Dropdown is visible at a time, and which one is visible is conditional on what the user chooses (i.e., we use a callback). Here’s a minimal example:

import dash
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output

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

controls = dbc.Card(
    [
        dbc.FormGroup(
            [
               dbc.Label("Choose input or dropdown"),
               dbc.RadioItems(
                   id='radio',
                   options=[
                       {'label': 'input', 'value': 'input'},
                       {'label': 'dropdown', 'value': 'dropdown'},
                   ],
                   value='input',
               ),
            ]
        ),
        dbc.FormGroup(
            [
                dbc.Label("Input", id='input-label'),
                dbc.Input(
                    id='input',
                    type='number',
                    min=1, max=100, step=1, value=5
                ),
            ]
        ),
        dbc.FormGroup(
            [
                dbc.Label("Dropdown", id='dropdown-label'),
                dcc.Dropdown(
                    id='dropdown',
                    options=[
                        {'label': 'Hello'+str(i), 'value': 'Hello'+str(i)} for i in range(100)
                    ],
                    multi=True,
                    placeholder='Say Hello',
                ),
            ]
        ),
    ],
    body=True,
    color='light',
)

app.layout = dbc.Container(
    [
        dbc.Row(
            [
                dbc.Col(controls, md=4)
            ],
            align='center',
        ),
    ],
    fluid=True,
)

@app.callback(
    [Output('input', 'style'),
     Output('input-label', 'style'),
     Output('dropdown', 'style'),
     Output('dropdown-label', 'style')],
    [Input('radio', 'value')])
def visibility(selected_type):
    if selected_type == 'input':
        return {'display': 'block'}, {'display': 'block'}, {'display': 'none'}, {'display': 'none'}
    else:
        return {'display': 'none'}, {'display': 'none'}, {'display': 'block'}, {'display': 'block'}


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

However, using the callback ruins the functionality of the Dropdown. For example, try including 10 or so “Hello’s” in the Dropdown. Now, if you comment out the callback in the code, the functionality is restored: adding many “Hello’s” causes the Dropdown box to expand to store them, as intended.

Could someone explain why my callback is causing this behaviour?

If anyone else has this problem, please see https://stackoverflow.com/questions/61270058/dash-dropdown-component-callback-visibility-bug