Adam Sewell
Adam Sewell

Reputation: 131

Filter Dash Table using callback function

I am trying create a web application suing dash that will display a table that can be filtered by a dropdown menu based a on value in a column but can't get to work

As I have multiple table to update I first created a function to create a Dash DataTable from a df (previously imported from a database)

def make_leaderboard(df):
return html.Div([
    dash_table.DataTable(
        columns=[{"name": i, "id": i} for i in df.columns],
        data=df.to_dict('records'),
        style_header={
            'backgroundColor': red,
            # 'fontWeight': 'bold',
            'color': 'white',
            'border': '0px',
            'font_family': 'Roboto',
            'font_size' : '15px',
            'line_height': '30px',
            'whiteSpace': 'normal',
        },
        style_cell={'padding': '5px', 'border': '0px', 'textAlign': 'center', 'font_family': 'Roboto', 'fontWeight': '100', 'font_size' : '14px', 'line_height': '28px'},
        style_data_conditional=[
        {
            'if': {'row_index': 'odd'},
            'backgroundColor': light_grey,
        }
        ],
        style_cell_conditional=[
        {
        'if': {'column_id': c},
            'textAlign': 'left'
        } for c in ['']
        ],
        style_as_list_view=True,
        page_action='native',
        fixed_rows={'headers':True},
        style_table={'height': '350px', 'overflowY': 'auto'},
    ),
    html.Br([]),
    ])

I then created a dash layout with dropdown and table

app.layout = html.Div([
    Header(),
    #row
    html.Div([
        html.Div([
            html.Div([
                html.H6(['SELECT POSITION'],),
                dcc.Dropdown(
                    id='select_position',
                    options=[
                        {'label': 'POINT GUARD', 'value': 'PG'},
                        {'label': 'SHOOTING GUARD', 'value': 'SG'},
                        {'label': 'SMALL FORWARD', 'value': 'SF'},
                        {'label': 'POWER FORWARD', 'value': 'PF'},
                        {'label': 'CENTER', 'value': 'C'}
                    ],
                    searchable=True,
                    multi=True,
                    style={'width':'90%'},
                ),
            ], className='four columns'),
        ], className="row container-display",),
    ],
    ),

    #row
    html.Div([
        html.Div([
            html.Div([
                html.H6(['TWO POINT PERCENTAGE'],),
                html.Div(make_leaderboard(data)),
            ], className='four columns', id='df_two_perc'),
        ], className="row container-display",),
    ],
    ),
],

)

And attempted to generate the callback

    @app.callback(
    Output(component_id='df_two_perc', component_property='data'),
    [Input(component_id='select_position', component_property='value')]
)
def update_df_div(option_selected):
    filtered_df = df_two_leaderboard[df_two_leaderboard['POS'].isin(option_selected)]
    data = filtered_df.to_dict('records')
    return data


if __name__ == '__main__':
    app.run_server(debug=True)

I am trying to filter by position (PG, SG, SF, PF, C) and return the filtered datable. The error I am getting at the moment is

NameError: name 'data' is not defined

So I assume it is not picking up the return of the data, but am unsure of the next steps to try and resolve this or even if I am remotely close to solving. Any help would be appreciated as I can't seem to find any specific resources in regards to tables and filtering in this way, thank you

Upvotes: 3

Views: 5658

Answers (1)

coralvanda
coralvanda

Reputation: 6596

You've attached the ID to the wrong component. It should be on the table, not the containing div.

You have:

html.Div([
                html.H6(['TWO POINT PERCENTAGE'],),
                html.Div(make_leaderboard(data)),
            ], className='four columns', id='df_two_perc'),  # this should be a different id!

You have not set an ID on the table. You need to make sure you have

    dash_table.DataTable(
        id='df_two_perc',
        columns=[{"name": i, "id": i} for i in df.columns],
        ...

Upvotes: 2

Related Questions