Context :
I have a Dash app with a dropdown and a map.
The map displays 3 markers with IDs : '01', '02' and '03'. I am able to click on a marker and return its ID through a callback.
The dropdown enables me to choose a marker by its ID.
What I want to do is to update the selected value in the dropdown with the selected marker on the map.
Example : I want to choose '02'. I can do it either by selecting '02' in the dropdown, or clicking on '02' on the map. But if I select it from the map, I want the selected value from the dropdown to be updated to '02'.
How can I update the Dropdown selected value from a value returned by a callback ?
Here is a reprex :
# -*- coding: utf-8 -*-
import dash.dependencies
import dash_bootstrap_components as dbc
import pandas as pd
import dash_leaflet as dl
from dash import dcc, html, Input, Output
########################################################################################################################
# VARIABLES
df_sites = pd.DataFrame([['01', (48.805, 2.326)], ['02', (43.167, 0.969)], ['03', (48.812, 2.530)]],
columns=['id_tech', 'coordonnees'])
circlemarkers = [dl.CircleMarker(
dl.Tooltip(df_sites.iloc[i]['id_tech']),
center=pos,
radius=2,
id=df_sites.iloc[i]['id_tech'])
for i, pos in enumerate(df_sites['coordonnees'])]
########################################################################################################################
# APP
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div([
dbc.Col([
dbc.Row([
# Following dropdown selected value should be updated when clicking on the map
dcc.Dropdown(df_sites['id_tech'].tolist(), df_sites['id_tech'].tolist()[0],id="in_choix_site"),
html.Br(),
dl.Map([dl.TileLayer(),
dl.GestureHandling(),
dl.LayerGroup(id="container", children=circlemarkers)
],
center=[47.285549, 2.300576],
zoom=4,
style={'height': '200px', 'width':'90%', 'margin':'10px'}),
"Selected from dropdown",
html.Div(id='from_dropdown'),
html.Br(),
"Selected from map",
html.Div(id='from_map')
])
], md=4)
])
@app.callback(Output("from_dropdown", "children"),
Input("in_choix_site", "value"))
def selected_site(dropdown_value):
return(dropdown_value)
@app.callback(Output("from_map", "children"),
[Input(marker.id, "n_clicks") for marker in circlemarkers])
def marker_click(*args):
marker_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]
return marker_id
if __name__ == '__main__':
app.run_server(debug=True)
So thanks to a coworker, I got the answer !
It was actually pretty obvious but since I am new to Dash I didn't figured it out right away. I just needed to add my Dropdown as an output of a callback. I am leaving this answer here in case someone else is having the same issue.
@app.callback([Output("from_map", "children"),
Output("in_choix_site", "value")],
[Input(marker.id, "n_clicks") for marker in circlemarkers])
def update_dropdown(*args):
marker_id = dash.callback_context.triggered[0]["prop_id"].split(".")[0]
return marker_id, marker_id