I’m trying to convert a working callback to a clientside callback for updating the columnState
for an AG-Grid table.
The goal is to update a ranking column based on user input. I do this by showing/hiding the appropriate ranking column and setting the sort in the columnState
.
Here’s a basic working example that dumps the columnState
to the page for debugging:
import json
import dash_ag_grid as dag
from dash import Dash, Input, Output, State, callback, clientside_callback, dcc, html
app = Dash(__name__)
dat = [
{"fruit": "apple", "bob_rank": 1, "alice_rank": 3},
{"fruit": "orange", "bob_rank": 2, "alice_rank": 4},
{"fruit": "banana", "bob_rank": 3, "alice_rank": 2},
{"fruit": "pear", "bob_rank": 4, "alice_rank": 1},
]
columnDefs = [
{"field": "bob_rank"},
{"field": "alice_rank", "hide": True},
{"field": "fruit"},
]
app.layout = html.Div(
[
html.Div(dcc.RadioItems(id="rank-select", options=["bob", "alice"], value="bob")),
dag.AgGrid(
id="table",
rowData=dat,
columnDefs=columnDefs,
),
html.Div(html.Pre(id="output")),
]
)
@callback(
Output("output", "children"),
Input("table", "columnState"),
)
def output(state):
return json.dumps(state, indent=2)
@callback(
Output("table", "columnState"),
Input("rank-select", "value"),
State("table", "columnState"),
)
def update_sort_state(rank, state):
if state is not None:
for col in state:
sort = None
hide = col["hide"]
if "rank" in col["colId"]:
hide = True
if col["colId"] == f"{rank}_rank":
sort = "asc"
hide = False
col.update({"sort": sort, "hide": hide})
return state
If I convert the callback to a clientside callback it no longer works, but the columnState
seems to be getting updated just like it does using the regular callback.
clientside_callback(
"""
function(rank, state) {
if (state) {
for (var i = 0; i < state.length; i++) {
col = state[i]
sort = null
hide = col['hide']
if (col['colId'].includes('rank')) {hide = true}
if (col['colId'] == rank + '_rank') {
sort = 'asc'
hide = false
}
update = {'sort': sort, 'hide': hide}
state[i] = {...col, ...update}
}
}
return state
}
""",
Output("table", "columnState"),
Input("rank-select", "value"),
State("table", "columnState"),
)
I can’t figure out the difference that makes the regular callback work, but the clientside callback not work. Ideas?