Currently, for dash_table filtering, once I refresh the page, the filter value is emptied.
I am looking for a way to retain data_table column filter value after refreshing page. What I am thinking is storing the filter value probably in dcc.Store and using that value to populate the filter later after page refresh.
Is there a way to achieve so using callback functions?
As best as I can tell the store is only available after the page loads, so you could easily have a âsave filterâ and âload filterâ button or an interval that runs once and disables itself. Hereâs an example of the latter:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash_table import DataTable
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Interval(id='filter-load', interval=50),
dcc.Store(id='filter-store', storage_type='local'),
DataTable(
id='dt',
columns=[{
'name': x,
'id': x
} for x in ['a', 'b', 'c', 'd']],
export_format='xlsx',
editable=True,
filter_action='native',
sort_action='native',
data=[{
'a': 'a' + str(x),
'b': 'b' + str(x) + str(x),
'c': 'c' + str(x) + 'c',
'd': 'd' + str(x) + '-' + str(x)
} for x in range(0, 100)]
)
])
@app.callback(output=dash.dependencies.Output('filter-store', 'data'),
inputs=[dash.dependencies.Input('dt', 'filter_query')])
def save_filter(filter_query):
if filter_query is None:
raise dash.exceptions.PreventUpdate
return filter_query
@app.callback(output=[dash.dependencies.Output('dt', 'filter_query'),
dash.dependencies.Output('filter-load', 'disabled')],
inputs=[dash.dependencies.Input('filter-load', 'n_intervals')],
state=[dash.dependencies.State('filter-store', 'data')])
def load_filter(n_intervals, stored_filter):
if n_intervals is None:
raise dash.exceptions.PreventUpdate
return stored_filter, True
if __name__ == '__main__':
app.run_server(debug=True)
Another option might to load the whole datatable as a callback this way, then you wonât have this second of seeing the unfiltered version of the table .
Building on this⌠Accessing Store data is somewhat difficult on load, but local/session storage IS accessible through JavaScript directly. Using clientside callbacks to access session / local storage data in order to populate the tableâs filter parameter may be one way to go.
An untested example to give you an idea of what this would look like:
dash python app
...
app.clientside_callback(
ClientsideFunction('myAppNamespace', 'preloadQuery'),
Output('dt', 'filter_query'),
[Input('filter-load', 'n_intervals')]
)
""" note: you can use any Input as all callbacks are triggered on load """
in your assets folder create a javascript file with the following contents:
if (!window.dash_clientside) {
window.dash_clientside = {};
}
let STORE = window.sessionStorage;
let TABLEQUERY_STORE_KEY = "table-query-filter";
let TABLEQUERY_DEFAULT = "LIMIT_TO_THIS_TEXT";
window.dash_clientside.myAppNamespace = {
preloadQuery: function(trigger) {
let query = STORE.getItem(TABLEQUERY_STORE_KEY);
if (query == undefined) {
query = JSON.stringify(TABLEQUERY_DEFAULT);
}
return query;
},
}
The above doesnât update session storage (you can use Damianâs example) but will grab from it if it exists.
Thanks for your solution. Inspired by the way you provided, I did find a way to retain the filter value and output the stored value in filter_query without using interval. The Store modified_timestamp should be triggered on the initial page load. When the modified_timestamp is triggered, the call back will take the stored value and use it for âfilter_queryâ. Since the Store is in Session type, the value is only cleared when browser is closed.