Dash Multipage app drill through to another page by making selection in table

I have a multipage app. The app pages are market.py and profile.py. This is how i register those pages:

market.py: dash.register_page(name, path=“mkt-to-mkt”)
profile.py: dash.register_page(name, path=“profile”)

In market.py I have a dash datatable with this layoud and callback (below). As you can see one of the tables columns is Building Name.

dash_table.DataTable(id='table-mkt', row_selectable='single')  # allow single selection

# Callback: Generate Table
@callback(
    Output("table-mkt", "data"),
    Output("table-mkt", "columns"),
    Input("submit-mkt", "n_clicks"),
    State("tree-select-region-mkt", "value"),
    State("tree-select-country-mkt", "value"),
    State("tree-select-city-mkt", "value"),
    State("tree-select-property-mkt", "value"),
    State("tree-select-ownership-mkt", "value"),
    State("tree-select-bu-mkt", "value"),
)
def update_table(n_clicks, region, country, city, sel_property, ownership, bu):

    # If n_clicks is None, display df with specified columns
    if n_clicks is None:
        columns = [{'name': 'Lease ID', 'id': 'LeaseID'}, {'name': 'Building Name', 'id': 'Building Name'}]
        return mkt_df.to_dict('records'), columns

    else:
        df_to_use = mkt_df[(mkt_df['Region'].isin(region)) &
                           (mkt_df['Country'].isin(country)) &
                           (mkt_df['City'].isin(city)) &
                           (mkt_df['Building Type'].isin(sel_property)) &
                           (mkt_df['Ownership Type'].isin(ownership)) &
                           (mkt_df['Business Unit'].isin(bu))]

        # Select columns
        columns = [{'name': 'Lease ID', 'id': 'LeaseID'}, {'name': 'Building Name', 'id': 'Building Name'}]
        return df_to_use.to_dict('records'), columns

Now in my profile.py page, I have building dropdown:

  dmc.Select(
      data=[{'label': i, 'value': i} for i in df['Building Name'].unique()],
      value=df.iloc[0]['Building Name'],
      id="building-id",
  )

What i want to achieve is the following. When the user selects a row from dash datatable in market.py page, i want building profile page building dropdown to automatically populate the building name that the user selected in the market.py page. Ideally, i also want that as soon as user makes a row selection in dash datatable in market.py i want to automatically be transfered to building profile page with the dropdown set to building name from selected row.

Any guidance pleas e?

Hi @GabrielBKaram

If you would like to switch to using Dash AG Grid, you can find an example here where you can have a link in the column to take you to different page. It also shows how to use path variables, so you can send the building name to the layout in the profile page. It would looks something like:

dash.register_page( __name__,  path_template="/profile/<building>")

def layout(building=None, **other_unknown_query_strings):

select = dmc.Select(
      data=[{'label': i, 'value': i} for i in df['Building Name'].unique()],
      value=building,  # passed to the layout from the URL
      id="building-id",
  )

See example 12

If you want to stick with the DataTable, you could update the URL in a callback. See examples 15 and 16. They don’t use DataTable, but the callback to navigate to the new page will be similar.

Hi @AnnMarieW , thanks for the reply! Just wondering what is meant by **other_unknown_query_strings?

so my profile.py page all the layout should fall in a function?

Hi @GabrielBKaram

Great question!

Pages will automatically send the path variables and query string variables to the layout function of a page. You can find out more info in the docs.

In most cases, you as the app developer will make the links that will show in the URL, however, there isn’t anything to prevent a user from adding a query string by typing it into the browser. So someone could make the URL in your app look like:

/profile/empire-state-building?x=1

It would pass to the layout function:

layout(building='empire-stat-building', x=1)

If you had the layout defined like this you would see an error :
def layout(building=None):

Of course you could call it anything you like but **other_unknown_query_strings is pretty descriptive.

And yes, if you define the layout as a function, you would return the entire layout.

Thanks @AnnMarieW for the explanation and guidance. I tried the code and it worked !

1 Like