DCC Range Slider With Dyanamic Input Boxes

Hello, I am trying to get the dyamic input box to work with dcc.RangeSlider per the original example with dcc.Slider found here:

The code below does not work, any ideas would be appreciated.

Thank you,

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

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [
        dcc.RangeSlider(
            id="slider", min=0, max=20, 
            marks={i: str(i) for i in range(21)}, 
            value=[3,5]
        ),
        dcc.Input(
            id="input", type="number", min=0, max=20, value=3
        ),
        dcc.Input(
            id="input1", type="number", min=0, max=20, value=3
        ),
    ]
)
@app.callback(
    Output("input", "value"),
    Output("input1", "value"),
    Output("slider", "value"),    
    Output("slider1", "value"),    

    Input("input", "value"),
    Input("input1", "value"),
    Input("slider", "value"),
    Input("slider1", "value"),

)
def callback(input_value, input_value1,slider_value,slider_value1):
    ctx = dash.callback_context
    trigger_id = ctx.triggered[0]["prop_id"].split(".")[0]
    print(trigger_id,'WTFFFFFFFFFFFF')
    value = input_value if trigger_id == "input" else slider_value
    value1 = input_value1 if trigger_id == "input1" else slider_value1
    return value, value,value1,value1
if __name__ == '__main__':		
    app.run_server(debug=False)

Hi @cocainesteamedrice

In your layout you don’t have any id named slider1, and you are using it as Input and Output :thinking:

The solution is in this post : Dash range slider which able to interact with input field that display range slider value - #3 by AnnMarieW :slight_smile:

1 Like

Thank you AnnMarieW I will have a look.

Hello AnnMarieW

I have an additional question now. In my original app I generate a range slider with dynamic max and min values. Is this still possible to do with the dynamic input boxes? I am trying to replicate the code you sent but am having difficulty displaying the range slider.

My current code looks like this:

    @app.callback(		
        [Output('slider-output-container', 'children'),#This is required to actually show the slider for some reason		
        Output('start_value', 'value'),#new shiot    		
        Output('end_value', 'value'),#new shiot
        Output('slider', 'value'),#new shiot
        
        
    ],		
         [Input("start_value", "value"),#new shiot    				
          Input("end_value", "value"),#new shiot    		
          Input('slider', 'value'),		

          
          Input("metmin", "children"),		
          Input("metmax", "children"),
          Input('atparentmet','value'),
          Input('atmet','value')])		
    def update_output(start,end,slider,metmin,metmax,atparentmet,atmet):		
        if atparentmet == 'Candlesticks' or "Up " in atmet or "Down " in atmet or "Reversal" in atmet:
            return html.Div(dcc.RangeSlider(id='slider', min = metmin, max = metmax, step=abs(((metmax-metmin)))))
        else:
            ctx = dash.callback_context
            trigger_id = ctx.triggered[0]["prop_id"].split(".")[0]
        
            start_value = start if trigger_id == "start_value" else slider[0]
            print(start_value,'soysauce')
            end_value = end if trigger_id == "end_value" else slider[1]
            print(end_value,'soysauce')
            slider_value = slider if trigger_id == "slider" else [start_value, end_value]
            print(start_value,'soysauce')
            return html.Div(dcc.RangeSlider(id='slider', min = metmin, max = metmax, step = abs(((metmax-metmin)/100)))),start_value, end_value, slider_value

and the app layout looks like this:

html.Div([		
html.P(		
        id='slider',		
    ),		
		
    html.Div(id='slider-output-container',		
		
),		
    ],		
        style={'textAlign':'center','height':'100px','left':'870px','paddingTop':'0px','top':'16px','position':'absolute','textAlign':'left','right':'259px','zIndex':'5000','borderRadius':'5px','marginLeft':'0px','marginBottom':'0px'},		
    		
    		
		
    ),		
	

 html.Div([                    		
               		
                dcc.Input(className="range_high",		
                    		
                    type='number',		
                    id='start_value',		
                    #placeholder="Low",		
                    style={'backgroundColor':'#fff','paddingLeft':'20px','textTransform':'none','height':'42px','borderRadius':'5px', 'fontSize':'13px','paddingTop':'6px'}		
                    ),		
]   		
                , 		
        style={'width':'70px','top':'6px','position':'absolute','left':'813px','zIndex':'5000','borderRadius':'5px','paddingTop':'5px','height': '40px','marginLeft':'0px','marginBottom':'20px'},		
                ),		
		
   html.Div(		
           [		
            html.Div([                    		
               		
                dcc.Input(className="range_high",		
                    		
                    type='number',		
                    id='end_value',		
                    #placeholder="High",		
                    style={'backgroundColor':'#fff','textTransform':'none','height':'42px','borderRadius':'5px', 'fontSize':'13px','paddingTop':'6px'}		
                    ),		
]		
                , ),	

Thank you very much.

Hi @cocainesteamedrice

It looks like your are returning only one item - a Div with a slider, but you have 4 Outputs in your callback.

I’d recommend splitting this into two callbacks. One would set the min, max, step of the slider, then the other would be the callback like in the link I posted which would sync the two input boxes to the slider.

1 Like

Hi AnnMarieW thanks a lot for your reply. In the lower part of the code I am returning all outputs, it is a bit confusing there, sorry about that.

How would I make the slider have dynamic min and max if I put the min and max in a different callback and am putting the slider itself in the app layout. Right now I am returning a slider to the app layout which allows me to have the dyanmic min and max. I think this is where it is conflicting with the dynamic inputs.

Thanks a lot,

-Steamrice.

You can update the min and max parameters in a callback

1 Like

Thanks AnnMarieW, do you have an example by chance? I was under the impression I would have to assign an id to the min or max which I can’t really figure out because it would be like mind=id=β€˜min_setting’ or something similar.

Thank you very much.

Sure - here’s a start. But it would need a lot more to make the UI nicer - like updating the value of the input boxes to reflect valid to-from values etc:


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

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [
        html.H4("Synchronized Components"),
        dcc.RangeSlider(
            id="slider",
            min=0,
            max=20,
            marks={i: str(i) for i in range(21)},
            value=[5, 15],
        ),
        "Start Value:",
        dcc.Input(id="start_value", type="number", min=0, max=20, value=5),
        "End Value:",
        dcc.Input(id="end_value", type="number", min=0, max=20, value=15),
        "Min Value:",
        dcc.Input(id="min_value", type="number", min=0, max=20, value=0),
    ]
)


@app.callback(
    Output("start_value", "value"),
    Output("end_value", "value"),
    Output("slider", "value"),
    Input("start_value", "value"),
    Input("end_value", "value"),
    Input("slider", "value"),
)
def callback(start, end, slider):
    ctx = dash.callback_context
    trigger_id = ctx.triggered[0]["prop_id"].split(".")[0]

    start_value = start if trigger_id == "start_value" else slider[0]
    end_value = end if trigger_id == "end_value" else slider[1]
    slider_value = slider if trigger_id == "slider" else [start_value, end_value]

    return start_value, end_value, slider_value


@app.callback(
    Output('slider', 'min'),
    Output('start_value', 'min'),
    Output('end_value', 'min'),
    Input('min_value', 'value')
)
def update_min(min):
    return min, min, min



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

Ok thanks a lot! I’m going to give this a shot.

Hi AnnMarieW I just wanted to let you know that this worked for me. Thank you very much for your help!

Glad to know it helped - thanks :slight_smile:

1 Like