Connecting a Text Area and a Dropdown


I was wondering if there is a way to have a specific text area for each member of a dropdown. What I want is when I change the dropdown the text area is different for that dropdown. I have tried using

dcc.Store(id = ‘memory-output-conditions’)

and then

@app.callback(Output('memory-output-conditions', 'data'),
                [Input('MCNDropdown', 'value')])
def filter_conditions(mcn1):

@app.callback(Output('conditions', 'data'),
            [Input('memory-output-conditions', 'data')])
def on_data_set_table(data):

but I’m not sure what to put in the callback.

Hi @Wooden_Kludge

Here is one way to do it. In this example, I’m assuming that the user can update the text area. If that’s the case, it would be better to include a submit button so that the callback isn’t triggered with every keystroke. If this is just for displaying data, then the callback can be much simpler since you wouldn’t need to have the Textarea as an input.


import dash
from dash import html, dcc, Input, Output, State

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Dropdown(
            id="dropdown",
            options=[
                {"label": "New York City", "value": "NYC"},
                {"label": "Montréal", "value": "MTL"},
                {"label": "San Francisco", "value": "SF"},
            ],
            value="MTL",
        ),
        dcc.Textarea(id="text"),
        dcc.Store(id="store", data={}),
    ],
)


@app.callback(
    Output("store", "data"),
    Output("text", "value"),
    Input("dropdown", "value"),
    Input("text", "value"),
    State("store", "data"),
)
def update(val, text, data):
    ctx = dash.callback_context
    input_id = ctx.triggered[0]["prop_id"].split(".")[0]

    if input_id == "text":
        data[val] = text
        return data, dash.no_update
    else:
        return dash.no_update, data.get(val, "")


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


How would you include a submit button so that the callback isn’t triggered with every keystroke? The different ways I tried did not seem to come to fruition. I am relatively new to dash and somewhat piecing things together.

Hi @Wooden_Kludge

First, add a button to the layout and as an Input in the callback.
Then change:

Input("text", "value"),

to

State("text", "value"),

That way, the button n_clicks prop would trigger the callback. The text value would not trigger the callback, but the value is available in the callback.

If this is confusing, let me know and I’ll update the example. Also, you can find out more about callback with State here

1 Like

I think I am getting close but missing just the most minor thing.
What I have is

@app.callback(
     Output("textstore", "data"),
Output("commenttext", "value"),
Input("MCNDropdown", "value"),
Input('submit-val', 'n_clicks'),
State("text", "value"),
State("textstore", "data"),
 )


def update(val,n_clicks, value, data):
ctx = dash.callback_context
input_id = ctx.triggered[0]["prop_id"].split(".")[0]
if 'submit-val'  ....
    data[val] = value
    return data, dash.no_update
else:
    return dash.no_update, data.get(val, "")

But I am unsure about what to put in the if statement and how to update it fully.

Here is a complete mwe:


import dash
from dash import html, dcc, Input, Output, State

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Dropdown(
            id="dropdown",
            options=[
                {"label": "New York City", "value": "NYC"},
                {"label": "Montréal", "value": "MTL"},
                {"label": "San Francisco", "value": "SF"},
            ],
            value="MTL",
        ),
        dcc.Textarea(id="text"),
        html.Button("Submit", id="submit"),
        dcc.Store(id="store", data={}),
    ],
)


@app.callback(
    Output("store", "data"),
    Output("text", "value"),
    Input("dropdown", "value"),
    Input("submit", "n_clicks"),
    State("text", "value"),
    State("store", "data"),
)
def update(val, n_clicks, text, data):
    ctx = dash.callback_context
    input_id = ctx.triggered[0]["prop_id"].split(".")[0]

    if input_id == "submit":
        data[val] = text
        return data, dash.no_update
    else:
        return dash.no_update, data.get(val, "")


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

1 Like