title: Dynamically updating dropdown options with 2 Inputs in callback Dash
body: <p>I am stuck in a part where I want to update the Batch dropdown in 2 ways. If there is nothing selected in Material dropdown, the batch dropdown should show all the Batches, but as soon as Material is selected, it should change to only show Batches for that Material type.</p>
  <p>This is what the relevant code looks like right now:</p>
  <pre><code>import dash
  from dash import dcc
  from dash import html
  from dash.dependencies import Input, Output 
  import plotly.express as px
  import pandas as pd
  import re
  
  app = dash.Dash(__name__)
  
  # Convert PARQUET to CSV
  
  
  df = pd.read_csv(&quot;release_cln.csv&quot;)
  
  # Store all unique values from Basis column
  
  df_dis = df[df['Analysis_Name_CLN'].str.contains(&quot;Dissolution&quot;).fillna(False)]
  
  df_dis['Batch'] = df_dis['Batch'].fillna(9999)
  df_dis['Basis'] = df_dis['Batch'].fillna(9999)
  df_dis['Material'] = df['Material'].fillna(9999)
  
  batch = df_dis['Batch'].unique()
  material = df_dis['Material'].unique()
  basis = df_dis['Basis'].unique()
  
  #[{'label': i, 'value': i} for i in material]
  
  app.layout = html.Div([
      html.H1(children='Comparing Batches'),
      html.H2('Dissolution vs Timepoint'),
  
      # Batch 1 Dropdowns
      html.Div([
          html.Div(
              html.H3(children='''DP Batch''')
          ),
          html.Div([
              html.Div(children='''Batch: '''),
              dcc.Dropdown(
                      id='batch_dd',
                      multi=False,
                      clearable=True,
                      disabled=False
                  ),
              ],style={'width': '20%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Material: '''),
              dcc.Dropdown(
                      id='material_dd',
                      multi=False,
                      clearable=True,
                      disabled=False
                  ),
              ],style = {'width': '15%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Basis: '''),
              dcc.Dropdown(
                      id='basis_dd',
                      multi=False,
                      clearable=True,
                      disabled=False
                  ),
              ],style = {'width': '15%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Variant: '''),
              dcc.Dropdown(
                      id='variant_dd',
                      multi=False,
                      clearable=True,
                      disabled=False
                  ),
              ],style = {'width': '10%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Analysis: '''),
              dcc.Dropdown(
                      id='analysis_name_dd',
                      multi=False,
                      clearable=True,
                      disabled=False,
                      options=[]
                  ),
              ],style = {'width': '40%','display': 'inline-block'}
          )
          ],style = {'width': '90%', 'display': 'inline-block'}
      ),
  
      html.Br(),
  
      # Batch 2 Dropdowns
      html.Div([
          html.Div(
              html.H3(children='''DS Batch''')
          ),
          html.Div([
              html.Div(children='''Batch: '''),
              dcc.Dropdown(
                      id='batch_dd_1',
                      multi=False,
                      clearable=True,
                      disabled=False,
                      options=[{'label': i, 'value': i} for i in batch]
                  ),
              ],style={'width': '20%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Material: '''),
              dcc.Dropdown(
                      id='material_dd_1',
                      multi=False,
                      clearable=True,
                      disabled=False,
                      options=[],
                  ),
              ],style = {'width': '15%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Basis: '''),
              dcc.Dropdown(
                      id='basis_dd_1',
                      multi=False,
                      clearable=True,
                      disabled=False,
                      options=[]
                  ),
              ],style = {'width': '15%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Variant: '''),
              dcc.Dropdown(
                      id='variant_dd_1',
                      multi=False,
                      clearable=True,
                      disabled=False,
                      options=[]
                  ),
              ],style = {'width': '10%','display': 'inline-block'}
          ),
          html.Div([
              html.Div(children='''Analysis: '''),
              dcc.Dropdown(
                      id='analysis_name_dd_1',
                      multi=False,
                      clearable=True,
                      disabled=False,
                      options=[]
                  ),
              ],style = {'width': '40%','display': 'inline-block'}
          )
          ],style = {'width': '90%', 'display': 'inline-block'}
      ),
  
      html.Br(),
      dcc.Graph(id='dissol_tp')
  ])
  
  ## Batch 1 Dropdowns
  #Call back to update Batch options if user searches for Batches
  @app.callback(
      Output('batch_dd','options'),
      [Input('batch_dd','search_value'),
      Input('material_dd','value')]
  )
  def batch_options(search_value, material_dd):
      if material_dd is None:
          return [{'label': i, 'value': i} for i in batch]
      else:
          batch_df = df[df['Material']==material_dd]
          return [{'label':i,'value':i} for i in batch_df['Batch'].fillna('None').unique()]
  
  
  @app.callback(
      Output('material_dd','options'),
      Input('material_dd','search_value'))
  def material_options(search_value):
      return [{'label': i, 'value': i} for i in material]
  
  # Callback to select default value in basis list
  @app.callback(
      Output('basis_dd','options'),
      Input('basis_dd','search_value'))
  def variant_default(batch_dd):
      return [k['value'] for k in batch_dd]
  
  # Chained callback to select variants with the selected batch
  @app.callback(
      Output('variant_dd','options'),
      Input('batch_dd','value'))
  def get_variant(batch_dd):
      batch_df = df[df['Batch']==batch_dd]
      return [{'label':i,'value':i} for i in batch_df['Variant'].fillna('None').unique()]
  
  
  </code></pre>
  <p>What's happening currently is batch dropdown shows all the batch values even when a material value is selected and doesn't change dynamically</p>