Dash Ag Grid: Output Selected Rows in the Order Sorted or Dragged with Checkboxes

I want to create an application that outputs the selected rows in the order they are sorted or dragged in Dash Ag Grid, using checkboxes. I attempted to use the selectedRows property as a callback state for output, but it doesn’t contain information about the order. How can I achieve my goal?

Here’s my code:

from dash import Dash, dcc, html, Input, Output, State, ALL, MATCH, callback, ctx, clientside_callback, no_update
import pandas as pd
import dash
import dash_ag_grid as dag

df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/iris.csv"
)
app = dash.Dash(__name__)

columnDefs = [
    {"field": "Name"},
    {"field": "SepalWidth"},
    {"field": "PetalLength"},
    {"field": "PetalWidth"},
    {"field": "SepalLength"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="dag",
            rowData=df.to_dict("records"),
            columnDefs=columnDefs,
            columnSize="autoSize",
            defaultColDef=dict(
                resizable=True,
                sortable=True,
                filter=True,
                editable=True,
                floatingFilter=True,
                minWidth=100,
                checkboxSelection={
                    "function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
                },
                headerCheckboxSelection={
                    "function": 'params.column == params.columnApi.getAllDisplayedColumns()[0]'
                },
            ),
            dashGridOptions={
                "animateRows": False,
                "enableCellTextSelection": True,
                "ensureDomOrder": True,
                "rowDragManaged": True,
                "rowDragMultiRow": True,
                "rowSelection": "multiple",
                "rowDragEntireRow": True,
                "pagination": True,
                "paginationPageSize": 20,
                "suppressRowClickSelection": True,
            },
        ),
        html.Button('display', id='btn-display', n_clicks=0),
        html.P(id="output")
    ]
)


@app.callback(
    Output("output", "children"),
    Input("btn-display", "n_clicks"),
    State("dag", "selectedRows"),
    prevent_initial_call=True,
)
def output_selected_rows(n_clicks, selected_rows):
    output = []
    print(n_clicks)
    print(selected_rows)
    if selected_rows is not None:
        for row in selected_rows:
            output.append(f"{row['Name']}, SepalWidth: {row['SepalWidth']}")
            output.append(html.Br())
        return output
    else:
        return "No selected"


if __name__ == '__main__':
    app.run(debug=True)

Output:
Here, rows are being reordered by dragging.

The expected output should be as follows.

Iris-setosa, SepalWidth: 3
Iris-setosa, SepalWidth: 3.2
Iris-setosa, SepalWidth: 3.1
Iris-setosa, SepalWidth: 3.5

Hello @mito.kc,

selectedRows is given directly by the underlying gird.

To have it in the displayed order, I recommend cross referencing it with the virtualRowData

rows = []
for x in virtualRowData:
    if x in selectedRows:
        rows.append(x)
return rows
2 Likes

@jinnyzor
Thank you very much! That’s works as expected.

1 Like