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 (themain_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 adcc.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 inmain_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 thesearch
attribute of the theurl
):
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!