Select all rows in Dash DataTable

Hi everyone!

I want to have select/deselect all rows functionality for a DataTable with either a checkbox or a button. I saw some old posts which suggested that a select-all checkbox used to be a part of DataTable but I couldn’t find any info on it in the documentation.

I’d appreciate any help with this. Thanks!

1 Like

Hi @shanv
I don’t think that is possible right now.

I managed to find a workaround using the selected_rows property and derived view port. I’ve made Select All and Deselect All buttons in the layout as inputs. For anyone else looking for the same functionality please refer to the snippet below:

@app.callback(
    [Output('in-table', 'selected_rows'),],
    [Input('select-all-button', 'n_clicks'),
    Input('deselect-all-button', 'n_clicks')],
    [State('in-table', 'derived_virtual_data'),]
)
def select_deselect(selbtn, deselbtn, selected_rows):
    ctx = dash.callback_context
    if ctx.triggered:
        trigger = (ctx.triggered[0]['prop_id'].split('.')[0])
    if trigger == 'select-all-button':
        if selected_rows is None:
            return [[]]
        else:
            return [[i for i in range(len(selected_rows))]]
    else:
        return [[]]
3 Likes

@shanv Thank you for your workaround!

I’ve adapted your code to create a “reset_plot_button”

@app.callback(
    [Output(component_id='main_datatable', component_property='selected_rows'),
     Output(component_id='main_datatable', component_property='sort_by')],
    [Input(component_id='button_reset_plot', component_property='n_clicks'),],)
def select_deselect(button_reset_plot_n_clicks):
    ctx = dash.callback_context
    # trigger = ""
    if ctx.triggered:
        print(ctx.triggered)
        trigger = ctx.triggered[0]["prop_id"].split(".")[0]
        if trigger == "button_reset_plot":
            return [], []

This function will not select the correct rows if filters are applied.
With Dash Documentation
We can add an “id” row in the dataframe as the index row of the data-frame as input.
And the function below can fix the error.:

@app.callback(
    Output('in-table', 'selected_rows'),
    Input('viz-select-all-btn', 'n_clicks'),
    Input('viz-deselect-all-btn', 'n_clicks'),
    State('in-table', 'derived_virtual_row_ids'),
)
def select_deselect(select_n_clicks, deselect_n_clicks, selected_rows):
    """Select or deselect all rows."""
    ctx = dash.callback_context
    trigger = None
    if ctx.triggered:
        trigger = (ctx.triggered[0]['prop_id'].split('.')[0])
    if trigger == 'viz-select-all-btn':
        if selected_rows is None:
            return []
        else:
            return selected_rows
    else:
        return []

Hello, I tried implementing both @shanv and your versions for my DataTable. For some reason, when I click the “Select All” button, nothing happens. Everything looks fine code-wise (double-checked to make sure I’m pointing to the right callback variables) and I used some print statements to make sure my application is reaching the return selected_rows statement (it is) but it doesn’t check off all the table’s boxes after I click it (my terminal is registering it being clicked though). Also, for some reason, after I added in either of your functions, I can’t individually check off any rows in my table anymore despite having row_selectable set to “multi”. Any idea what I could be missing? I made sure I’m not returning my table’s “selected_rows” attribute in any other callback function (but I am returning my table’s “data” attribute in another function if that matters).