title: create bootstrap drop down menu in plotly dash using one function to set it up
body: <p>The logic behind the dash core component dropdown and the dash bootstrap components is a bit different and I would like to have the best of both worlds: the nice style from dbc and the functionality from dcc. However, modifying the css for the dcc to make it look nicer is complicated and I could not find an existing solution. To set up the dbc component requires some set up effort as each element in the drop down has an own id. Also if you want to directly get from the dropdown what is the selected value  (if you ask the dropdown what are you actually showing) you cannot do that directly.</p>
  <p>I thus wanted to setup a function that sets the drop down and its callback up automatically but I run into the problem that the callback is a nested function and is therefore not available globally. How can I change that? Or is there another way to build it.</p>
  <p>What I want in the end is an easy way to set up the dbc dropdown such that it shows the selected value.
  This is what I have so far (the not working solution):</p>
  <pre><code>import dash
  import dash_bootstrap_components as dbc
  import dash_html_components as html
  from dash.dependencies import Input, Output
  
  
  def selectable_dropdown(item_id=&quot;dropdown&quot;, 
                          options=['option_1','option_2']):
      # create the items and the ids for each item
      dropdown_items = [dbc.DropdownMenuItem(item, id=item_id+'_'+item) 
                        for item in options]
  
      # create the dropdown menu
      dropdown = dbc.DropdownMenu(
                                  dropdown_items, 
                                  label=&quot;none&quot;, 
                                  addon_type=&quot;prepend&quot;,
                                  bs_size=&quot;sm&quot;,
                                  id=item_id
                                  )
          
      output = Output(item_id, &quot;label&quot;)
      inputs = [Input(item_id+'_'+item, &quot;n_clicks&quot;) for item in options]
      
      @app.callback(output,inputs)
      def update_label(*args):
          # get the triggered item
          ctx = dash.callback_context
          triggered_id = ctx.triggered[0][&quot;prop_id&quot;].split(&quot;.&quot;)[0]
          # get the label for the triggered id or return no selection
          if (np.array([n==None for n in args]).all()) or not ctx.triggered:
             return &quot;no selection&quot;
          else:
             return [label for label in options if item_id+'_'+label == triggered_id]            
      return dropdown       
  
  
  app = dash.Dash(
      external_stylesheets=[dbc.themes.BOOTSTRAP]
  )
  app.config['suppress_callback_exceptions'] = True
  
  app.layout = \
      html.Div([selectable_dropdown(item_id=&quot;target_select&quot;,
                                    options=[&quot;option1 &quot;, &quot;option 2&quot;, &quot;option3&quot;])])
      
          
  if __name__ == &quot;__main__&quot;:
      app.run_server(debug=False, host = '0.0.0.0', port = 1234)
  </code></pre>
  <p>thats how it should look like (a working example) but I wnat it in a more generalized way and in the best way just in one function or class:</p>
  <pre><code>import dash
  import numpy as np
  import dash_bootstrap_components as dbc
  import dash_html_components as html
  from dash.dependencies import Input, Output
  
  options=[&quot;option1 &quot;, &quot;option 2&quot;, &quot;option3&quot;]
  item_id = 'dropdown'
  dropdown_items = [dbc.DropdownMenuItem(item, id=item_id+'_'+item) 
                    for item in options]
  
  # create the dropdown menu
  dropdown = dbc.DropdownMenu(
                              dropdown_items, 
                              label=&quot;none&quot;, 
                              addon_type=&quot;prepend&quot;,
                              bs_size=&quot;sm&quot;,
                              id=item_id)
      
  output = Output(item_id, &quot;label&quot;)
  inputs = [Input(item_id+'_'+item, &quot;n_clicks&quot;) for item in options]
  
  app = dash.Dash(
      external_stylesheets=[dbc.themes.BOOTSTRAP,'./assets/stylesheet.css']
  )
  app.config['suppress_callback_exceptions'] = True
  
  app.layout = \
      html.Div([dropdown])
     
  @app.callback(output,inputs)
  def update_label(*args):
      # get the triggered item
      ctx = dash.callback_context
      triggered_id = ctx.triggered[0][&quot;prop_id&quot;].split(&quot;.&quot;)[0]
      # get the label for the triggered id or return no selection
      if (np.array([n==None for n in args]).all()) or not ctx.triggered:
          return &quot;no selection&quot;
      else:
          return [label for label in options if item_id+'_'+label == triggered_id]
   
          
  if __name__ == &quot;__main__&quot;:
      app.run_server(debug=False, host = '0.0.0.0', port = 1234)
  </code></pre>