Sorting

react-bootstrap-data-grid implements simple sorting of data, one column at a time, in ascending or descending order. The user can change the column being sorted and the sort order by clicking on a column header.

When a user clicks on a column header, the sort order changes between ascending, descending, and none. When the sort order is none, the rows in the table will appear in original order of the array in which data was passed to the Grid component.

Note that sorting is done on the original data, before pagination and before formatting functions are applied. In particular, note that numbers will be sorted by the value of the number rather than lexicographically. Similarly, dates and datetimes will be sorted by the number of milliseconds after the epoch time as opposed to any time of string representation of the Date object.

How to Enable

To allow a user to sort a Grid by a particular column, set the sortable property to true in the column definition (ColDef) for the column.

In addition, setting the sortModel property on the Grid component is required to enable sorting.

Controlled vs Uncontrolled

The sorting feature of react-bootstrap-data-grid is available in controlled and uncontrolled modes. Using controlled mode allows for the state to be read and written to externally, but requires more code to set up compared to uncontrolled mode.

In controlled mode, the variable representing the current state and the setter function for that variable are passed down from the parent component to the Grid component via the sortModel prop. Pass a prop of type ControlledTableSortModel to enable controlled mode.

In uncontrolled mode the Grid component itself contains the state with regards to sorting. When using this mode, one passes the starting state to the Grid component. This starting state is read only once when the Grid component mounts. Pass a prop of type UncontrolledTableSortModel to enable uncontrolled mode.

Type Definitions

See below for specifications for the sortModel property and related types.

TableSortModel

Union type that includes ControlledTableSortModel and UncontrolledTableSortModel. Passed to the Grid component to control the overall configuration of the grid with regards to sorting.

ControlledTableSortModel

Property nameType definitionRequired/OptionalDescription
type'controlled'Optional

Discriminator field between ControlledTableSortModel and UncontrolledTableSortModel. Marked optional for backwards compatibility.

sortColDefSortColDef | nullRequired

The current setting for sorting for the Grid. A null value means that no column is being sorted. If no column is being sorted, then the rows will appear in the order of the rows prop passed to the Grid component.

setSortColDef(sortColDef: SortColDef | null) => voidRequired

Callback function to set the state of sortColDef in response to user input

UncontrolledTableSortModel

Property nameType definitionRequired/OptionalDescription
type'uncontrolled'Required

Discriminator field between ControlledTableSortModel and UncontrolledTableSortModel.

initialSortColDefSortColDef | nullRequired

The initial state of the grid with regards to sorting. Note that due to the nature of React and useState, this prop will only take effect once, upon per mounting of the Grid component.

If you wish to update the sorting state of the grid externally, either unmount and remount the Grid component when doing so or use the sorting feature of the grid in controlled mode.

A null value means that no column is being sorted. If no column is being sorted, then the rows will appear in the order of the rows prop passed to the Grid component.

SortColDef

Property nameType definitionRequired/OptionalDescription
namestringRequiredThe name of the column to sort
order"asc" | "desc"RequiredThe sort order, ascending or descending

Examples

Both examples use the sample data from the following file:

sortedGridData.ts
import { ColDef, RowDef } from "@absreim/react-bootstrap-data-grid";
 
export const cols: ColDef[] = [
  {
    name: "name",
    type: "string",
    label: "Name",
    sortable: true,
  },
  {
    name: "damage",
    type: "number",
    label: "Average Damage",
    sortable: true,
  },
  {
    name: "dmgType",
    type: "string",
    label: "Damage Type",
  },
  {
    name: "weight",
    type: "number",
    label: "Weight (lb)",
    sortable: true,
  },
  {
    name: "price",
    type: "number",
    label: "Price",
    sortable: true,
  },
];
 
interface Data {
  name: string;
  damage: number;
  dmgType: string;
  weight: number;
  price: number;
}
 
export const rows: RowDef<Data>[] = [
  {
    id: "flail",
    data: {
      name: "Flail",
      damage: 4.5,
      dmgType: "Bludgeoning",
      weight: 2,
      price: 50,
    },
  },
  {
    id: "morningstar",
    data: {
      name: "Morningstar",
      damage: 4.5,
      dmgType: "Piercing",
      weight: 3.6,
      price: 50,
    },
  },
  {
    id: "rapier",
    data: {
      name: "Rapier",
      damage: 4.5,
      dmgType: "Piercing",
      weight: 1.8,
      price: 80,
    },
  },
  {
    id: "scimitar",
    data: {
      name: "Scimitar",
      damage: 4.5,
      dmgType: "Slashing",
      weight: 2.7,
      price: 30,
    },
  },
  {
    id: "war pick",
    data: {
      name: "War Pick",
      damage: 4.5,
      dmgType: "Piercing",
      weight: 1.8,
      price: 40,
    },
  },
  {
    id: "battleaxe",
    data: {
      name: "Battleaxe",
      damage: 5.5,
      dmgType: "Slashing",
      weight: 3.6,
      price: 50,
    },
  },
  {
    id: "longsword",
    data: {
      name: "Longsword",
      damage: 5.5,
      dmgType: "Slashing",
      weight: 2.7,
      price: 40,
    },
  },
  {
    id: "warhammer",
    data: {
      name: "Warhammer",
      damage: 5.5,
      dmgType: "Bludgeoning",
      weight: 5.4,
      price: 50,
    },
  },
  {
    id: "greataxe",
    data: {
      name: "Greataxe",
      damage: 6.5,
      dmgType: "Slashing",
      weight: 6.3,
      price: 65,
    },
  },
  {
    id: "greatsword",
    data: {
      name: "Greatsword",
      damage: 7,
      dmgType: "Slashing",
      weight: 5.4,
      price: 65,
    },
  },
  {
    id: "maul",
    data: {
      name: "Maul",
      damage: 7,
      dmgType: "Bludgeoning",
      weight: 9,
      price: 40,
    },
  },
];

Controlled

Code

ControlledSortedGrid.tsx
"use client";
 
import Grid, {
  SortColDef,
  TableSortModel,
} from "@absreim/react-bootstrap-data-grid";
import { rows, cols } from "./sampleSortedGridData";
import { FC, useState } from "react";
 
const SampleControlledSortedGrid: FC = () => {
  const [sortColDef, setSortColDef] = useState<SortColDef | null>({
    name: "name",
    order: "asc",
  });
 
  const tableSortModel: TableSortModel = {
    sortColDef,
    setSortColDef,
  };
 
  return <Grid rows={rows} cols={cols} sortModel={tableSortModel} />;
};
 
export default SampleControlledSortedGrid;

Live Demo

Name(sorted ascending)Up arrow indicating that the column is being sorted in an ascending mannerAverage DamageEmpty transparent square for styling purposesDamage TypeWeight (lb)Empty transparent square for styling purposesPriceEmpty transparent square for styling purposes
Battleaxe5.5Slashing3.650
Flail4.5Bludgeoning250
Greataxe6.5Slashing6.365
Greatsword7Slashing5.465
Longsword5.5Slashing2.740
Maul7Bludgeoning940
Morningstar4.5Piercing3.650
Rapier4.5Piercing1.880
Scimitar4.5Slashing2.730
War Pick4.5Piercing1.840
Warhammer5.5Bludgeoning5.450

Uncontrolled

The same functionality as the controlled example above can be implemented in uncontrolled mode, though in doing so the parent component loses access to the sorting state of the Grid.

Code

UncontrolledSortedGrid.tsx
"use client";
 
import Grid, { TableSortModel } from "@absreim/react-bootstrap-data-grid";
import { rows, cols } from "./sampleSortedGridData";
import { FC } from "react";
 
const SampleUncontrolledSortedGrid: FC = () => {
  const tableSortModel: TableSortModel = {
    type: "uncontrolled",
    initialSortColDef: {
      name: "name",
      order: "asc",
    },
  };
 
  return <Grid rows={rows} cols={cols} sortModel={tableSortModel} />;
};
 
export default SampleUncontrolledSortedGrid;

Live Demo

Name(sorted ascending)Up arrow indicating that the column is being sorted in an ascending mannerAverage DamageEmpty transparent square for styling purposesDamage TypeWeight (lb)Empty transparent square for styling purposesPriceEmpty transparent square for styling purposes
Battleaxe5.5Slashing3.650
Flail4.5Bludgeoning250
Greataxe6.5Slashing6.365
Greatsword7Slashing5.465
Longsword5.5Slashing2.740
Maul7Bludgeoning940
Morningstar4.5Piercing3.650
Rapier4.5Piercing1.880
Scimitar4.5Slashing2.730
War Pick4.5Piercing1.840
Warhammer5.5Bludgeoning5.450