How to limit the amount of inputs in a dropdown?

Greetings, currently my app has one multi dropdown that reflects all of my inputs for my callbacks. Things start getting slow on my dashboard when I select multiple inputs from my dropdown as there is no limit. How can I limit the amount of values a user can input in the dropdown? I’m not talking about options, just the amount of multi-values in my dropdown.

Hi,

You can achieve this with a callback (example with at most 2 active values):

@app.callback(
    Output("your-dropdown", "options"), [Input("your-dropdown", "value")],
)
def limit_drop_options(selected_values):
    """Limit dropdown to at most two actives selections"""
    if len(selected_values) >= 2:
        return [
            option
            for option in OPTIONS_DROPDOWN
            if option["value"] in selected_values
        ]
    else:
        return OPTIONS_DROPDOWN

You need for this to work to keep all your options in a global variable. As soon as two values are selected there are not any more option the users may select until they clear one.

You could even try to convert this example to a clientside callback since we do not really need the python backend here.

Good luck!

1 Like

Hey Batalex, Sorry for such a late response. I just used your method, it works really well, so thank you for sharing your code snippet. For some reason it feels like it slows down my app by just a little (most likely the combination of other callbacks). Would combining this callback with another one improve preformance?

EDIT:

To output a user warning that they hit a limit, I’ve tried this method but it doesn’t work?

@app.callback(

  Output("input-warning", 'children'), Output("dynamic-dropdown", "options"), [Input("dynamic-dropdown", "value")],
)
def limit_drop_options(symbols):
    """Limit dropdown to at most two actives selections"""
    if len(symbols) >= 5:

      children = html.P("You have entered the limit", id='input-warning')
      return [
          option
          for option in options
          if option["value"] in symbols
          children
          
      ]
    else:
        return options


Hi,
yes it slows a bit the app, as any other callback would. As I said previously, we do not need the Python backend for this. You could try to convert this to a clientside callback for better performances.

As for your followup question, here is what your callback should look like:

@app.callback(
  [Output("input-warning", 'children'), Output("dynamic-dropdown", "options")], [Input("dynamic-dropdown", "value")],
)
def limit_drop_options(symbols):
    """Limit dropdown to at most two actives selections"""
    if len(symbols) >= 5:

      children = html.P("You have entered the limit", id='input-warning')
      return [
          children,
          [option
          for option in options
          if option["value"] in symbols]
      ]
    else:
        return [[], options]

  1. Multi outputs should be grouped in a list in app.callback()
  2. You must always return as many elements as outputs, in the same order (or take a look at no_update)
  3. Your first return was invalid Python code
1 Like

This is awesome, thank you for showing me the how-to. Noted on the tips as well! :slight_smile:

I have noticed that this might not always be the best solution if your callback times take longer than a second. It’s possible for me to override the function due to the callbacks not finishing being registered, so a user can spam as many inputs they want before the callback is done setting off.