Interdependent components


#1

Hello,

I’ve had a lot of fun building a dashboard using Dash! I have run across a problem that I hope has a solution within Dash, although reading about similar users’ related problems I’m not sure.

Suppose I have two components (e.g. Slider, Dropdown, or Input) whose values are related. When I change the value of one, I want the other to change, and vice versa. This creates an obvious cyclic dependency, but this seems like something that should be accomplishable. Is it?

From a UI perspective, this can often be worked around, but I can think of cases where the natural inputs for a user have an interdependency. Suppose a user wants two dropdowns to select a city and chain restaurants. When they select a city, the restaurant dropdown should be populated by restaurants in that city, and when they select a restaurant, the city dropdown should be populated by cities that have that restaurant.

Here is a MWE with two Input components:

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

app = dash.Dash()
server = app.server

# define the layout of the dashboard
app.layout = html.Div([
    html.Div([
        html.H6('x'),
        dcc.Input(id='input_x'),
    ], className='row'),
    html.Div([
        html.H6('2x'),
        dcc.Input(id='input_2x'),
    ], className='row'),
])

# NOTE: This breaks because of a cyclic dependency
# not clear what can be done here.

# update input_x when input_2x changes
@app.callback(
    Output('input_x', 'value'),
    [Input('input_2x', 'value')]
)
def update_x(v):
    return v/2

# update input_2x when input_x changes
@app.callback(
    Output('input_2x', 'value'),
    [Input('input_x', 'value')]
)
def update_2x(v):
    return 2*v

app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'})

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

#2

I don’t know that there’s any workaround other than changing the UI to work differently.

I wonder also if there might be usability issues with this UI. If a user has selected a city, then the other drop down will be filtered to chains with restaurants in that city. Now if a user want’s to then select a specific chain, if it doesn’t occur in that city they selected, they then have to go and clear the city in the other dropdown before the desired chain will be available. In this case it seems like undesirable coupling between them; the filtering that might be a convenience in some contexts is now a friction point. And if the user isn’t fully aware of what’s going on with the filtering, they may incorrectly conclude that the desired chain is just not in the database.


#3

OK, thanks - I suspected that changing the UI is required.

You’re right that this example is not the best - perhaps there are generally friction points with this kind of interdependency.


#4

Yeah, this isn’t possible right now. But, it’s a valid concern. Here’s a classic example where this would be useful: a slider is synced up with the text input:


This will be quite a bit of work to support correctly. If any organization or company has the software budget to sponsor this work, please reach out: https://plot.ly/dash/pricing