Some thoughts on dash-table-experiments Dash DataTable

Just a few thoughts on the dash table component after making an app that uses it heavily.

The way that the selectable indices interacts with the filtering is sort of screwy – if I have row 1 selected, and now I set the filter such that row 1 has different content, it updates the selection to the new content. To my mind, this is very unlikely to ever be the desired behavior – the user is selecting based on content, not based on row number. Perhaps selected_row_indices could work on the initial list of rows instead of the filtered one?

I often find the columns do not take up the entire width of the table. This must be some initialization bug because if I change the size of the browser window by any tiny amount, the columns expand to fill the table.

A couple of features would be nice: I’m pretty sure most of these have already been mentioned, just adding another vote.

  • select only one row
  • disable “select all” checkbox
  • select by just clicking on the row instead of the checkbox

Sorry for the multiple topics in one post – happy to put some of them into new issues.

1 Like

This shouldn’t happen. Here’s the demo from usage.py

My guess is that your data has duplicate rows or something, in which case I recommend adding a column of invisible IDs (as a workaround for now): bug in select with duplicate rows · Issue #16 · plotly/dash-table-experiments · GitHub

Also, thanks for sharing the feedback!

This shouldn’t happen. Here’s the demo from usage.py

@chriddyp You’re right of course. I had a callback that reset the row selection when the table changed, and I didn’t realize it was getting called when the filter got activated.

(the other weird filter issue I mentioned still persists).

1 Like

I’m curious as to how the callback looked like in order to be able to reset the row selection… using the selected_row_indices property as an Output, doesn’t work: it results in a Error loading dependencies for me.

# -*- coding: utf-8 -*-
import json
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
import dash_table_experiments as dt



app = dash.Dash()
app.scripts.config.serve_locally = True
# app.config['ignore_callback_exceptions'] = True

app.layout = html.Div([
    dt.DataTable(
        id='datatable',
        rows=[
            {'x': 'row-0', 'y': 0},
            {'x': 'row-1', 'y': 1},
            {'x': 'row-2', 'y': 2},
            {'x': 'row-3', 'y': 3},
            {'x': 'row-4', 'y': 4},
        ],
        row_selectable=True,
        selected_row_indices=[],
    ),
    html.Pre(id='selection')

])


@app.callback(
    Output('selection', 'children'),
    [Input('datatable', 'selected_row_indices')])
def show_selection(selection):
    return json.dumps(selection)


@app.callback(
    Output('datatable', 'selected_row_indices'),     #  <--- causes error loading dependencies
    [Input('datatable', 'selected_row_indices')])
def set_selection(selection):
    print('set_selection:', selection)
    return selection[0:1]


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

In the above, the second callback takes advantage of the fact that the last row index to be selected seems
to be the first one listed. So returning only the first index as a list to update the selected_row_indices should
turn the multi-select into a single-select… if not for the error loading dependencies.

The selected_row_indices property seems to be read-only…

I think your problem is the circular dependence created by your callback.

Something like this works fine for me:

@app.callback(
    Output('datatable', 'selected_row_indices'), 
    [Input('reset_button', 'n_clicks')])
def reset_selection(n_clicks):
    return [0]

I’m not sure you can accomplish backdoor single-selection this way.

Thanks and it looks like you’re right. Resetting the selected_row_indices via the button works indeed,
but not via a callback triggered (directly or indirectly) by a change in the selected_row_indices itself.

I suspect it would be easier to implement selection_type = single or multiple at the JS side of the table component.
i also need this capability