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 Table 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 Table 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 Table component via the sortModel prop. Pass a prop of type ControlledSortModel to enable controlled mode.

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

Examples

Both examples use the sample data from the following file:

tableData.ts
import { ColDef, RowDef } from "@absreim/react-bootstrap-data-grid/table";
 
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

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

Live Demo

NameAverage DamageDamage TypeWeight (lb)Price
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 Table.

Code

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

Live Demo

NameAverage DamageDamage TypeWeight (lb)Price
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