Defaulting to a dropdown value without loosing ability for other option(s) selection

Hi,

I’m working on app that contains three dropdowns: sample-dropdown, method-dropdown, and trace-dropdown. The options and values of trace-dropdown are meant to change based on the selected values from the other two dropdowns.

Here are the behaviors I’m aiming for:

  1. When more than one method is selected in method-dropdown, I want the trace-dropdown to only display the “Method label” option and have its value set to “Method_label”. This is working as intended in below code.

  2. If after that event, only one method is selected, I’d like the value of trace-dropdown to be “Sample” (default value). However, the user should still see all options available (“Sample”, “Method label”, and “Form”) and be able to select them.

My current implementation always sets the trace-dropdown value to “Sample” when a single method is selected, which prevents the user from choosing another option. Is there a way where I could only revert back to default option while not making it obligatory?

Here’s my callback function:

@callback(
    [Output("trace-dropdown", "options"),
     Output("trace-dropdown", "value")],
    [Input("trace-dropdown", "value"),
     Input("sample-dropdown", "value"),
     Input('method-dropdown', 'value'),
     ])  

def update_dropdowns(trace_value, selected_batches, selected_methods):
    trace_options = [{"label": "Sample", "value": "Sample"},
                     {"label": "Method label", "value": "Method_label"},
                     {"label": "Form", "value": "Form"}]
    
    if len(selected_methods) > 1:
        trace_options = [{"label": "Method label", "value": "Method_label"}]
        trace_value = "Method_label" 
        
    elif len(selected_methods) == 1 and trace_value not in [opt["value"] for opt in trace_options]:
        trace_value = "Sample"
    
    return trace_options, trace_value

I was a bit too quick with the question. Simple usage of state can be a solution.

from dash.dependencies import Input, Output, State

@callback(
    [Output("trace-dropdown", "options"),
     Output("trace-dropdown", "value")],
    [Input("sample-dropdown", "value"),
     Input('method-dropdown', 'value')],
    [State("trace-dropdown", "value")]
)  

def update_dropdowns(selected_batches, selected_methods, current_trace_value):
    trace_options = [
        {"label": "Sample", "value": "Sample"},
        {"label": "Method label", "value": "Method_label"},
        {"label": "Form", "value": "Form"}
    ]
    
    if len(selected_methods) > 1:
        trace_options = [{"label": "Method label", "value": "Method_label"}]
        trace_value = "Method_label"
        
    elif len(selected_methods) == 1 and current_trace_value == "Method_label":
        trace_value = "Sample"
    
    else:
        trace_value = current_trace_value
    
    return trace_options, trace_value

1 Like

Or, you could utilize no_update

from dash import Input, Output, State, no_update

@callback(
    [Output("trace-dropdown", "options"),
     Output("trace-dropdown", "value")],
    [Input("sample-dropdown", "value"),
     Input('method-dropdown', 'value')],
)  

def update_dropdowns(selected_batches, selected_methods):
    trace_options = [
        {"label": "Sample", "value": "Sample"},
        {"label": "Method label", "value": "Method_label"},
        {"label": "Form", "value": "Form"}
    ]
    
    if len(selected_methods) > 1:
        trace_options = [{"label": "Method label", "value": "Method_label"}]
        trace_value = "Method_label"
        
    elif len(selected_methods) == 1 and current_trace_value == "Method_label":
        trace_value = "Sample"
    
    else:
        trace_value = no_update
    
    return trace_options, trace_value