Changing the ids to dicts shouldn’t be a problem. You could do it like this:
# Instead of this
id='dropdown_{}'.format(col_name)
# Write this
id = {'type':'component', 'index': "dropdown_{}".format(col_name)}
I have specified ‘type’:‘component’ instead of ‘type’:‘dropdown’ because as I see in your code, you do the same things in the callbacks for both dropdowns and inputs so they can be treated as the same to keep it simple. If you wanted to do different thinks it would be more appropriate to specify ‘type’:‘dropdown’ and ‘type’:‘input’. The names don’t really matter as long as they match through the code.
Anyway, the resulting (full) code would look something like this:
def generate_components(tab, col_name):
output_title = html.H3(id="change_{}".format(col_name),children = "Change {} :".format(col_name))
if tab[col_name].dtypes== object:
list_options=[]
for k in tab[col_name].unique():
list_options.append({'label':k,'value':k})
output_component = html.Div([dcc.Dropdown(options = list_options,
#id='dropdown_{}'.format(col_name),
id = {'type':'component', 'index': "dropdown_{}".format(col_name)},
value= tab.at[0,col_name]
)])
else :
output_component = html.Div([dcc.Input(
#id="input_{}".format(col_name),
id = {'type':'component', 'index': "input_{}".format(col_name)},
type="number",
value= tab.at[0,col_name])
])
return (dbc.Row([
dbc.Col(children=output_title, width={'size': 4, 'offset': 1}),
dbc.Col(children=output_component, width={'size': 4, 'offset': 1})
])
)
#list_id_components=[]
#for col_name in tab.columns:
# if tab[col_name].dtypes== object:
# list_id_components.append('dropdown_{}'.format(col_name))
# else :
# list_id_components.append('input_{}'.format(col_name))
list_element=['value']*len(tab.columns)
@app.callback(
Output({'type':'component', 'index':ALL}, 'value'),
Input('datatable-r', 'selected_rows')
)
def maj_values_dropdowns(selected_rows):
if len(selected_rows) !=0:
name = tab.iloc[selected_rows[0]]['Name']
tab_values = tab.loc[tab['Name'] == name,:].iloc[0,:]
return ([value for value in tab_values])
@app.callback(
Output('datatable-s', 'data'),
Input('datatable-r', 'selected_rows'),
Input({'type': 'component', 'index': ALL}, 'value')
)
def disclose_selected_r(selected_rows, *args):
name = tab.iloc[selected_rows]['Name']
tab_columns=pd.DataFrame(tab.columns, index=tab_reactors.columns)
tab_int = tab.copy()
tab_int.query('Name' == name) = [values for values in [args]]
tab_r = pd.concat([tab_columns,tab_int.query('Name' == name).T], axis=1)
tab_r = tab_r.to_dict('records')
return (tab_r)
I have commented the list_id_components loop because with the pattern-matching is not necessary anymore.