Black Lives Matter. Please consider donating to Black Girls Code today.

Checkbox/radiobutton changing when I change slider values

I have the following piece of test code:

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

# Layout
app = dash.Dash()

app.layout = html.Div([
    # Tools
    html.Div([
        html.Div([
            html.H3('Signal Options'),
            html.Label('Show signal type:', style={'fontWeight': 'bold'}),
            dcc.RadioItems(
                id='signal_type_radio',
                options=[
                    {'label': 'Raw', 'value': 'raw'},
                    {'label': 'Filtered', 'value': 'filtered'},
                    {'label': 'Both', 'value': 'both'}
                ], labelStyle={'display': 'inline-block'}
            ),
            dcc.Checklist(
                id='flip_signal_btn',
                options=[
                    {'label': 'Flip signal', 'value': 'flip'}
                ],
                values=[]
            ),
            html.Br(),
            html.Label('Filter order:', id='filter-order-label', style={'fontWeight': 'bold'}),
            dcc.Slider(
                id='filter_order_slider',
                min=2,
                max=20,
                step=1,
                marks={2:'2', 20:'20'},
                dots=True,
                updatemode='drag'
            ),
            html.Br(),
            html.Label('Filter threshold:', id='filter-threshold-label', style={'fontWeight': 'bold'}),
            dcc.Slider(
                id='filter_threshold_slider',
                min=1,
                max=20,
                step=1,
                marks={1:'1', 20:'20'},
                dots=True,
                updatemode='drag'
            ),
            html.Br(),
            html.Br(),
            html.Button(['Set Default Options'], id='default_options_btn', style={'width': '100%'}, className="button")
        ], className="four", style={'borderStyle': 'solid', 'borderWidth': '1px', 'padding': '10px', 'padding-top': '0px'})
    ], style={'height': '100%', 'width':'25%', 'float':'left'})

], style={'padding': '0px'})
    
# Callbacks
## Widget labels
@app.callback(Output('filter-order-label', 'children'),
              [Input('filter_order_slider', 'value')])
def display_filter_order(value):
    return 'Filter order: {}'.format(value)

@app.callback(Output('filter-threshold-label', 'children'),
              [Input('filter_threshold_slider', 'value')])
def display_filter_threshold(value):
    return 'Filter threshold: {}Hz'.format(value)

## Signal options
@app.callback(Output('signal_type_radio', 'value'),
              [Input('default_options_btn', 'n_clicks'),])
def set_default_signal_type(value):
    return 'filtered'

@app.callback(Output('flip_signal_btn', 'values'),
              [Input('default_options_btn', 'n_clicks'),])
def set_default_flip(value):
    return []

@app.callback(Output('filter_order_slider', 'value'),
              [Input('default_options_btn', 'n_clicks'),])
def set_default_filter_order(value):
    return 2

@app.callback(Output('filter_threshold_slider', 'value'),
              [Input('default_options_btn', 'n_clicks'),])
def set_default_filter_threshold(value):
    return 10


if __name__ == '__main__':
    app.run_server(port=8060, threaded=True, debug=True)

If I change the radio selection or check the checkbox, and then change either of the slider values, both the radio and checkbox values get reset. Almost like their callbacks are being called

I’m not sure why this is happening because the sliders arent set up to act as inputs for changing the radio/checkbox values (only to change a label)

Unrelated question: right now I have a “set default” button that just resets the values of 4 things. I don’t believe a callback can have multiple outputs, so is there a more efficient way of writing this than with 4 separate callbacks?

I think this might be due to the RadioItems and Checklist components not being used as inputs for any callback in that example. This has come up before here. I think this will right itself once you wire them up as Inputs for callbacks, which I’m presuming you either meant to do or do soon.

Yeah, you can’t have multiple outputs for a callback, although this might change at some point. If the elements to be cleared are located contiguously within the layout you could just have that part of the layout, which includes all the things needing clearing, be (re)generated through a callback (both on initial page load and for when you press the clear button).

Otherwise you do need four different callbacks. Using the app.callback function as a function rather than a decorator can make this a bit more streamlined. See this post for inspiration.