Click Data for more details

A while back, I used a tool called Rails_admin, which came with a functionality, where I could display a partial table of data (subset of all the columns) and then when I clicked on a specific data point in the table, it brought me to a new page which displayed all of the information about that specific data point. Is this possible with Dash? https://github.com/sferik/rails_admin for reference

Yes, it is, although it’s a little convoluted. This is how I go about doing this:

  • I have a multi-page app: the first page (/) contains the main table; the second (/details) shows another table (table_details) with the details of the cell clicked in the first page’s table. Here are the layout and page callback (the main_page is defined elsewhere):
app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])


@app.callback(
    Output('page-content', 'children'),
    [Input('url', 'pathname')]
)
def display_page(pathname):
    if pathname == '/details':
        return html.Div([
            dcc.Link('Back to main page', href='/'),
            html.Br(),
            html.Div(id='table-details', style={'margin': '0 auto'})
        ])
    else:
        return main_page

  • I create the table in the first page (main_page) with html, and I dynamically make each cell a dcc.Link which contains the information of the column and row of the table in the query part of the url (the part after the question mark). Here you can see a simplified example of how I build the rows of the html table in main_page from the dataframe:
[html.Tr(
    [html.Td(
        dcc.Link(
            dataframe.iloc[i][col],
            href=f'/details?row={i}&col={col}',
            refresh=False
        )
    ) for col in dataframe.columns
    ]
) for i in range(len(dataframe))
]
  • Finally, the table_details table shown in the /details page is created through a callback that takes the query part of the url (which contains the row and column info of the cell clicked in the main page) as an input (you do this through the search attribute of the the url):
from urllib.parse import urlparse, parse_qs

@app.callback(
    Output('table-details', 'children'),
    [Input('url', 'search')]
)
def show_details(search):
    parsed_url = urlparse(search)
    parsed_search = parse_qs(parsed_url.query)
    # parsed_search will contain a dictionary with the 'row' and 
    # 'col' clicked in the original table, which you can use to create
    # the response you want to show in the details table
    .
    .
    .
    return details_object

Hope this helps you get started!

3 Likes