How to sort dash table so selected rows are always first?

Hello,

I am using a DataTable with multi row select enabled. Does anyone have a callback handy which will sort the selected rows so that those which are selected are always shown first / at the top?

Thank you

Hi @dowens1994 and welcome to the Dash community :slight_smile:

This isn’t easy to do with the Dash DataTable, but give dash-ag-grid a try!

Here is an example in the docs that does a post sort and places certain rows at the top.

You can modify this example in the link above to make selected rows at the top. Check this out::

ag-grid-sort-selected-top


import dash_ag_grid as dag
from dash import Dash, html
import pandas as pd

app = Dash(__name__)

df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)

columnDefs = [
    {"field": "athlete", "checkboxSelection": True, "headerCheckboxSelection": True},
    {"field": "age"},
    {"field": "country"},
    {"field": "year"},
    {"field": "sport"},
    {"field": "total"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="row-sorting-post-sort",
            rowData=df.to_dict("records"),
            columnDefs=columnDefs,
            defaultColDef={"resizable": True, "sortable": True},
            columnSize="sizeToFit",
            dashGridOptions={
                "postSortRows": {"function": "postSortSelected(params)"},
                "rowSelection":"multiple"
            }
        ),
    ]
)

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


Put this in the dashAgGridFunctions.js file in the assets folder:

var dagfuncs = (window.dashAgGridFunctions = window.dashAgGridFunctions || {});

dagfuncs.postSortSelected = function (params) {
    const rowNodes = params.nodes;
    // here we put selected rows on top while preserving the sort order
    let nextInsertPos = 0;
    for (let i = 0; i < rowNodes.length; i++) {
        const selected = rowNodes[i].isSelected();
        if (selected) {
            rowNodes.splice(nextInsertPos, 0, rowNodes.splice(i, 1)[0]);
            nextInsertPos++;
        }
    }
}

2 Likes

I appreciate the answer. Looks like a nice library.