Hi, I am working on a dash data table where I am making a drill down report. I have been following along with
[https://github.com/amyoshino/Dash_Tutorial_Series/tree/master/Table_Drill_Down]
as an example. It does what I want for the most part, but I am running into an issue of needing to “do nothing” on certain situations.
Here is a sample pseudo-code of what I have:
# load necessary data
my_df = pd.DataFrame(...)
# define an initial dataframe to display
init_df = pd.DataFrame(...)
app.layout = dhc.Div(
[
dcc.Store(id='memory'),
dhc.Div(
[
dhc.H4(
'EIDs Used Between '
, id='page_title'
, style={'display': 'inline-block'}
),
dcc.DatePickerRange(
id='date_range_picker'
, min_date_allowed=dat(2019, 6, 22).date()
, end_date=dat(currentDT.year, currentDT.month, currentDT.day).date()
, start_date=dat(currentDT.year, currentDT.month, 1).date()
, style={'display': 'inline-block', 'marginLeft': 10}
)
],
id='date_picker_container'
),
dhc.Div(
[
dhc.Button(
'Reset Table'
, id='reset_table_button'
, style={'width': '10%', 'display': 'inline-block'}
)
], style={'display': 'inline-block', 'width': '100%'}
, id='buttons_container'
),
dhc.Div(
children=[
dhc.Div(
dt.DataTable(id='table', page_size=20)
, id='init_table_div'
, hidden=False
),
],
id='table_container',
)
],
id='page_container'
)
def generate_table(dataframe, out_id='table'):
return dt.DataTable(
id=out_id
, data=dataframe.to_dict('records')
, columns=[{'id': c, 'name': c} for c in dataframe.columns]
, page_action='native'
, page_size=20
)
@app.callback(
Output('table_container', 'children'),
[
Input('table', 'selected_cells')
, Input('date_range_picker', 'start_date')
, Input('date_range_picker', 'end_date')
, Input('reset_table_button', 'n_clicks_timestamp')
# , Input('table', 'data')
],
[State('memory', 'data')]
)
def update_init_table_data(sel, start_date, end_date, reset_button, current_table):
if start_date is not None:
start_date = dat.strptime(start_date, '%Y-%m-%d').date()
if end_date is not None:
end_date = dat.strptime(end_date, '%Y-%m-%d').date()
# if we have nothing in the current table, then fill the table with the initial df
if not current_table:
return generate_table(init_df, 'table')
if not current_table['data']:
# print('Table is none')
return generate_table(init_df, 'table')
if reset_button is None:
reset_button = 0
stamp = str(time.time())[:10]
if stamp == str(reset_button)[:10]:
return generate_table(init_df, 'table')
# put current table keys into a list
curr_keys = [*current_table['data'][0].keys()]
# set the unique column name
unq_key = curr_keys[2]
res = my_df.copy()
# do some initial filtering that is done for all tables based on date
res = res[res['Date'] >= start_date]
res = res[res['Date'] <= end_date]
# if there is a selection, handle that case:
if sel:
print('in sel')
row_num = sel[0]['row']
col_id = sel[0]['column_id']
if unq_key == 'SomeColumn':
if col_id == 'ApplicationName':
# do some stuff
return generate_table(res, 'table')
if col_id == 'UserName':
# do some stuff
return generate_table(res, 'table')
if unq_key == 'SomeColumn':
# in top level and need to do something different for filtering dates
# do stuff based on being here
res = ...
if unq_key == 'UserName':
# do different things based on being here
res = ...
if unq_key == 'UsedApp':
# do other things based on being here
res = ...
return generate_table(res, 'table')
if __name__ == '__main__':
app.run_server(debug=True)
Ok, so in the above code, we have a call back that takes a date range picker, an active cell, and a reset button as the inputs. The output is the div container of the dashtable.
On every if statement in the update_table() function call, I return a generate_table() command so that we can update the table on screen with what the user does.
The problem is that when the data has too many rows, we automatically get the “Previous” and “Next” buttons so that the data becomes paginated. So, when the user selects the “Next” button on the table, it registers as a selection in the callback and triggers the callback. Which returns a table of the current data that was displayed prior to the selection of the "Next"button. Essentially, the next button triggers this callback and does not allow it to actually move to the next page.
What is the best way to handle this using Dash? If you want interactivity with the table but also the ability to see the next page, how do you do that?
Thanks for any help!