Selection
React Bootstrap Data Grid provides functionality for the user to select and deselect rows in a Grid component.
A Grid can be configured to configured to allow or disallow selection. If allowed, it can be configured to either allow selection of one row at a time or multiple rows at a time.
In addition, after configuring whether to allow single or multiple selection, it can be configured to allow selection by clicking on a row, by clicking on a radio or checkbox (single and multiple selection, respectively) for each row, or both.
If radio or checkbox selection is enabled (including the "both" option), the header cell for the column that contains radio or checkbox selection inputs will be clickable. Clicking on it will deselect any existing selected rows if there is currently one or more rows selected. If no rows are selected, clicking on the header cell selects all rows if multiple selection is enabled. If single selection is enabled while no existing row is selected, clicking on the header cell does nothing.
Type Definitions
SelectModel
Objects of type SelectModel are used to enable selection for a Grid, specify the mode (single vs multi), type (row, column, or both), and contain the state that keeps track of what rows are selected. Selected rows are tracked by original index of each row inside the array that is passed into Grid.
A SelectModel is one of two interfaces, SingleSelectModel and MultiSelectModel, for single selection and multiple selection modes, respectively.
MultiSelectModel
| Property name | Type definition | Required/Optional | Description |
|---|---|---|---|
| mode | SelectMode | Required | Specified whether to allow selection via inputs elements in a dedicated column, via clicking on rows, or both simultaneously |
| type | 'multi' | Required | A type discriminator used to differentiate between different selection modes |
| selected | number[] | Required | An array of index values that tracks the selected rows. Any rows with an index that is in this array is considered selected. |
| setSelected | (selected: number[]) => void | Required | Setter function to update the state that tracks the selected rows |
SingleSelectModel
| Property name | Type definition | Required/Optional | Description |
|---|---|---|---|
| mode | SelectMode | Required | Specified whether to allow selection via inputs elements in a dedicated column, via clicking on rows, or both simultaneously |
| type | 'single' | Required | A type discriminator used to differentiate between different selection modes |
| selected | number | null | Required | A number value to track the index of the currently selected row, or null if no row is selected. |
| setSelected | (selected: number | null) => void | Required | Setter function to update the state that tracks the selected row |
| groupName | string | Required | A string used for the 'name' property of radio input elements. It must be unique across the entire page to avoid unexpected behavior. |
SelectMode
A union of values that indicate the mode of selection.
- row
- Selection can only be done by clicking on the row. Selected rows are highlighted and when the mouse hovers over a row, the row is also highlighted (in a color different from that of selected rows.)
- column
- Selection can only be done by clicking on inputs elements in a dedicated column. Choosing this mode also enables a header cell that offers to select all or deselect all rows (exact functionality depends on the selection type, single or multi).
- both
- If this mode is chosen, functionality from both
rowandcolumnmodes will be active at the same time.
Examples
External Interaction
To have your app act on selected elements, simply read the row indices from the state that is passed down in your parent component and do something with it.
Code
"use client";
import { FC, useMemo, useState } from "react";
import Grid, { ColDef, MultiSelectModel, RowDef } from "@/grid";
import Button from "react-bootstrap/Button";
import Stack from "react-bootstrap/Stack";
const cols: ColDef[] = [
{
type: "number",
name: "number",
label: "Number",
},
];
const origRows: RowDef[] = [
{
number: 1,
},
{
number: 2,
},
{
number: 3,
},
{
number: 4,
},
{
number: 5,
},
];
const ExternalInteractionExample: FC = () => {
const [rows, setRows] = useState<RowDef[]>(origRows);
const [selected, setSelected] = useState<number[]>([]);
const selectModel: MultiSelectModel = useMemo(
() => ({
mode: "both",
type: "multi",
selected,
setSelected,
}),
[selected],
);
const deleteSelectedRows = () => {
setRows(rows.filter((_, index) => !selected.includes(index)));
setSelected([]);
};
const resetRows = () => {
setRows(origRows.slice());
};
return (
<Stack gap={2}>
<Grid rows={rows} cols={cols} selectModel={selectModel} />
<Stack direction="horizontal" gap={2} className="justify-content-end">
<Button
onClick={resetRows}
disabled={rows.length === origRows.length}
variant="secondary"
>
Reset
</Button>
<Button
onClick={deleteSelectedRows}
disabled={selected.length === 0}
variant="primary"
>
Delete Selected
</Button>
</Stack>
</Stack>
);
};
export default ExternalInteractionExample;
Live Demo
| Number | |
|---|---|
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 |
Multiple Selection Mode
Code
"use client";
import Grid, { ColDef, MultiSelectModel, RowDef, SelectMode } from "@/grid";
import { FC, useMemo, useState } from "react";
export interface SampleMultiSelectGridProps {
mode: SelectMode;
}
const cols: ColDef[] = [
{
name: "name",
type: "string",
label: "Name",
},
{
name: "damage",
type: "number",
label: "Average Damage",
},
{
name: "weight",
type: "number",
label: "Weight (lb)",
},
{
name: "price",
type: "number",
label: "Price",
},
];
const rows: RowDef[] = [
{
name: "Short Bow",
damage: 3.5,
weight: 1.8,
price: 16,
},
{
name: "Long Bow",
damage: 4.5,
weight: 2.2,
price: 50,
},
{
name: "Light Crossbow",
damage: 4.5,
weight: 4.5,
price: 30,
},
{
name: "Heavy Crossbow",
damage: 5.5,
weight: 16.2,
price: 65,
},
{
name: "Hand Crossbow",
damage: 3.5,
weight: 1.8,
price: 50,
},
];
const SampleMultiSelectGrid: FC<SampleMultiSelectGridProps> = ({ mode }) => {
const [selected, setSelected] = useState<number[]>([]);
const selectModel: MultiSelectModel = useMemo(() => ({
mode,
type: "multi",
selected,
setSelected,
}), [mode, selected]);
return <Grid rows={rows} cols={cols} selectModel={selectModel} />;
};
export default SampleMultiSelectGrid;
Live Demo
| Name | Average Damage | Weight (lb) | Price | |
|---|---|---|---|---|
| Short Bow | 3.5 | 1.8 | 16 | |
| Long Bow | 4.5 | 2.2 | 50 | |
| Light Crossbow | 4.5 | 4.5 | 30 | |
| Heavy Crossbow | 5.5 | 16.2 | 65 | |
| Hand Crossbow | 3.5 | 1.8 | 50 |
Single Selection Mode
Code
"use client";
import { FC, useMemo, useState } from "react";
import Grid, { ColDef, RowDef, SelectMode, SingleSelectModel } from "@/grid";
export interface SampleSingleSelectGridProps {
mode: SelectMode;
}
const cols: ColDef[] = [
{
name: "name",
type: "string",
label: "Name",
},
{
name: "school",
type: "string",
label: "School",
},
];
const rows: RowDef[] = [
{
name: "Acid Splash",
school: "Conjuration",
},
{
name: "Blade Ward",
school: "Abjuration",
},
{
name: "Bone Chill",
school: "Necromancy",
},
{
name: "Fire Bolt",
school: "Evocation",
},
{
name: "Minor Illusion",
school: "Illusion",
},
{
name: "Friends",
school: "Enchantment",
},
{
name: "Ray of Frost",
school: "Evocation",
},
];
const SampleSingleSelectGrid: FC<SampleSingleSelectGridProps> = ({ mode }) => {
const [selected, setSelected] = useState<number | null>(null);
const selectModel: SingleSelectModel = useMemo(() => ({
mode,
type: "single",
selected,
setSelected,
groupName: "single selection example grid (BG3 cantrips)"
}), [mode, selected]);
return <Grid rows={rows} cols={cols} selectModel={selectModel} />;
};
export default SampleSingleSelectGrid;
Live Demo
| Name | School | |
|---|---|---|
| Acid Splash | Conjuration | |
| Blade Ward | Abjuration | |
| Bone Chill | Necromancy | |
| Fire Bolt | Evocation | |
| Minor Illusion | Illusion | |
| Friends | Enchantment | |
| Ray of Frost | Evocation |