title: Updating dash datatable using callback function
body: <p>I have a dash dashboard I built. I would like to add more interactivity. I want to allow users to select an option on a drop down menu and the data shown in my datatable is filtered according to said selection</p>
  
  <p>This is how I have defined my datatable</p>
  
  <pre><code>html.Div([
      dash_table.DataTable(
          id='punchstats',
          columns=[{'name': i, 'id': i} for i in punch_stats.columns],
          data = punch_stats.to_dict('records'),
          page_current=0,
          page_size=2,
          page_action='custom',
          sort_action='custom',
          sort_mode='multi',
          style_table={'overflowX':'scroll',
                       'maxHeight':'300px'},
          style_header={'backgroundColor':'rgb(30, 30, 30)'},
          style_cell={'backgroundColor':'rgb(50,50,50)',
                      'color':'white'},
          sort_by=[]),
  ])
  </code></pre>
  
  <p>These are the drop down filters I have defined</p>
  
  <pre><code>dcc.Dropdown(
      id='weight_class',
      options=[{'label': i, 'value': i} for i in data['division'].unique()],
      multi=True
  ),
  dcc.Dropdown(
      id='gender',
      options=[{'label': i, 'value':i} for i in fight_outcomes['sex'].unique()],
      multi=True
  ),
  </code></pre>
  
  <p>and this is the function that should update my table according to the dropdown selections</p>
  
  <pre><code>@app.callback(
      dash.dependencies.Output('punchstats','data'),
      [dash.dependencies.Input('punchstats','page_current'),
       dash.dependencies.Input('punchstats','page_size'),
       dash.dependencies.Input('punchstats','sort_by'),
       dash.dependencies.Input('weight_class','value'),
       dash.dependencies.Input('gender','value')])
  def update_punchstats(page_current,page_size,sort_by,weight_class,gender):
      if weight_class is None or weight_class == []:
          weight_class == WEIGHT_CLASS
      if gender is None or gender == []:
          gender == GENDER
      punchstatsdf = [(punch_stats['division'].isin(weight_class))]
      punchstatsdf = [(punchstatsdf['sex'].isin(gender))]
      print(sort_by)
      if len(sort_by):
          sorted_df = punchstatsdf.sort_values(
              [cols['column_id'] for cols in sort_by],
              ascending=[
                  cols['direction'] == 'asc'
                  for col in sort_by
              ],
              inplace=False
          )
      else:
          sorted_df = punchstatsdf
      return sorted_df.iloc[page_current*page_size:(page_current+ 1)*page_size].to_dict('records')
  </code></pre>
  
  <p>Not sure how to add a minimum reproducible example for this type of question, hoping there is something wrong with the function logic that can be spotted by someone who has more experience with this package.</p>
  
  <p>Just to reiterate the problem. When I select a given weight class and/or gender the datatable does not filter data that specifically in the selected weight class/gender</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Through research I found out that in order to allow users to sort by column I had to change sort_action to native as custom implied that I had to specify the sort action myself. However I am still struggling to allow users to filter the data that appears in the data table based on the dropdown selection.</p>
  
  <p>Here is my updated code. I have also added:</p>
  
  <pre><code>html.Div([
          dash_table.DataTable(
              id='punchstats',
              columns=[{'name': i, 'id': i} for i in sorted(punch_stats.columns)],
              # data = punch_stats.to_dict('records'),
              page_current=0,
              page_size=5,
              page_action='native',
              sort_action='native',
              column_selectable="single",
              row_selectable="single",
              sort_mode='multi',
              style_table={'overflowX':'scroll',
                           'maxHeight':'300px'},
              style_header={'backgroundColor':'rgb(30, 30, 30)'},
              style_cell={'backgroundColor':'rgb(50,50,50)',
                          'color':'white'},
              sort_by=[]),
      ])
  </code></pre>
  
  <p>and:</p>
  
  <pre><code>@app.callback(
      dash.dependencies.Output('punchstats','data'),
      [dash.dependencies.Input('weight_class','value'),
       dash.dependencies.Input('gender','value')])
  def update_punchstats(weight_class,gender):
      if weight_class is None or weight_class == []:
          weight_class == WEIGHT_CLASS
      if gender is None or gender == []:
          gender == GENDER
      punchstatsdf = [(punch_stats['division'].isin(weight_class))]
      punchstatsdf = [(punchstatsdf['sex'].isin(gender))]
      return [
          punchstatsdf.to_dict('records')
      ]
  </code></pre>
  
  <p>I have also tried updating my dash datatable in my callback function by returning a dictionary:</p>
  
  <pre><code>def update_punchstats(weight_class,gender):
      if weight_class is None or weight_class == []:
          weight_class == WEIGHT_CLASS
      if gender is None or gender == []:
          gender == GENDER
      punchstats = [(punch_stats['division'].isin(weight_class))]
      punchstats = [(punchstats['sex'].isin(gender))]
      return {
          'data': punchstats.to_dict("records")
      }
  </code></pre>
  
  <p>However, this returns an empty datatable</p>
  
  <p>Here is the data I am using:</p>
  
  <pre><code>path_five = 'https://raw.githubusercontent.com/EmmS21/SpringboardCapstoneBoxingPredictionWebApp/master/boxingdata/punchingstats.csv'
  punch_stats = pd.read_csv(path_five)
  </code></pre>