Skip to content

Commit c684ea6

Browse files
authored
fix: respect multiSelect in checkbox and row keyboard selection (#2573)
* fix: respect `multiSelect` in checkbox and row keyboard selection
1 parent 98308e3 commit c684ea6

19 files changed

Lines changed: 220 additions & 22 deletions

File tree

demos/aurelia/src/examples/slickgrid/example30.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,6 @@ export class Example30 {
497497
preHeaderPanelHeight: 28,
498498
enableCheckboxSelector: true,
499499
enableSelection: true,
500-
multiSelect: false,
501500
checkboxSelector: {
502501
hideInFilterHeaderRow: false,
503502
hideInColumnTitleRow: true,

demos/react/src/examples/slickgrid/Example30.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,6 @@ const Example30: React.FC = () => {
492492
preHeaderPanelHeight: 28,
493493
enableCheckboxSelector: true,
494494
enableSelection: true,
495-
multiSelect: false,
496495
checkboxSelector: {
497496
hideInFilterHeaderRow: false,
498497
hideInColumnTitleRow: true,

demos/vue/src/components/Example30.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,6 @@ function defineGrid() {
456456
preHeaderPanelHeight: 28,
457457
enableCheckboxSelector: true,
458458
enableSelection: true,
459-
multiSelect: false,
460459
checkboxSelector: {
461460
hideInFilterHeaderRow: false,
462461
hideInColumnTitleRow: true,

docs/grid-functionalities/composite-editor-modal.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ Mass Update allows you to apply changes (from the modal form) to the entire data
143143

144144
Note however that there is a subtle difference compare to the Create Item action, you need to specifically tag which column will show up in the Mass Update and you need to do that by adding `massUpdate: true` flag inside the `editor` property of each column definition that you wish to be included in the form.
145145

146+
Important: `selectionOptions.selectActiveRow: false` is commonly used for checkbox-based multi-row workflows, but you must also keep `multiSelect` enabled (default `true`), otherwise `mass-selection` and `auto-mass` will not work as expected because only one row can stay selected at a time.
147+
146148
`auto-mass` option: If you decide to use Mass Update and Mass Selection and wish to only expose 1 button to do the action and let the system decide if it's doing a Mass Update or a Mass Selection change, you can use the modal type `auto-mass` (if it detect that some rows are selected it will use Mass Selection or else Mass Update). From our experience, user prefer to expose the 2 separate action buttons (less confusion), but this for you to decide, you have the option.
147149

148150
##### with TypeScript
@@ -237,6 +239,8 @@ example class MyCompositeDemo {
237239
## Mass Selection
238240
Similar to the Mass Update but apply changes only on the selected rows. The setup is nearly identical to the Mass Update, just make sure to display appropriate modal title. Also note that you also need to add `massUpdate: true` flag inside the `editor` property of each column definition that you wish to be included in the Mass Selection changes form.
239241

242+
**Important**: Mass Selection requires real multi-row selection, so even if you use `selectionOptions.selectActiveRow: false`, you must keep `multiSelect` enabled (default `true`); with `multiSelect: false`, only one row can remain selected and the modal will not behave as expected.
243+
240244
Refer to the [Mass Update](#mass-update) section for code sample.
241245

242246
`auto-mass` option: If you decide to use Mass Update and Mass Selection and wish to only expose 1 button to do the action and let the system decide if it's doing a Mass Update or a Mass Selection change, you can use the modal type `auto-mass` (if it detect that some rows are selected it will use Mass Selection or else Mass Update). From our experience, user prefer to expose the 2 separate action buttons (less confusion), but this for you to decide, you have the option.

docs/grid-functionalities/row-selection.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [Disable Custom Rows Selections via `selectableOverride`](#disable-custom-rows-selections-via-selectableoverride)
77
- [Disable External Button when having Empty Selection](#disable-external-button-when-having-empty-selection)
88
- [Change Row Selections](#change-row-selections)
9+
- [Understanding the multiSelect Option](#understanding-the-multiselect-option)
910
- Troubleshooting
1011
- [Adding a Column dynamically is removing the Row Selection column, why is that?](#adding-a-column-dynamically-is-removing-the-row-selection-column-why-is-that)
1112
- [Hybrid Selection Model (cell+row selection)](#hybrid-selection-model-and-drag-fill)
@@ -80,7 +81,7 @@ gridObjChanged(grid) {
8081
```
8182

8283
## Multiple Row Selections
83-
As for multiple row selections, you need to disable `enableCellNavigation` and enable `enableCheckboxSelector` and `enableRowSelection`. Then as describe earlier, you will subscribe to `onSelectedRowsChanged` (for that you need to bind to `(gridChanged)`). There are 2 ways to choose for the implementation of a row selection, option **1.** is the most common option and is the recommend way of doing it.
84+
As for multiple row selections, you need to enable `enableCheckboxSelector` and `enableRowSelection`, keep `multiSelect` enabled (default is `true`), and typically use `selectionOptions.selectActiveRow: false` when you do not want active-row clicks to interfere with checkbox-based multi-selection. Then as describe earlier, you will subscribe to `onSelectedRowsChanged` (for that you need to bind to `(gridChanged)`). There are 2 ways to choose for the implementation of a row selection, option **1.** is the most common option and is the recommend way of doing it.
8485

8586
### 1. with Custom Events (preferred way)
8687
You can also do it through a Custom Event listener since all SlickGrid events are exposed as Custom Events. For more info see [Wiki - OnEvents](grid-dataview-events.md)
@@ -112,6 +113,7 @@ export class Example1 {
112113
// True (Single Selection), False (Multiple Selections)
113114
selectActiveRow: false
114115
},
116+
// keep `multiSelect` enabled (default) for actual multiple row selection
115117
}
116118
}
117119

@@ -138,6 +140,7 @@ export class Example1 {
138140
// True (Single Selection), False (Multiple Selections)
139141
selectActiveRow: false
140142
},
143+
// keep `multiSelect` enabled (default) for actual multiple row selection
141144
}
142145
}
143146

@@ -339,6 +342,30 @@ export class Example1 {
339342
}
340343
```
341344

345+
## Understanding the `multiSelect` Option
346+
The `multiSelect` grid option is a critical setting that controls how row selection works across all selection methods (checkboxes, keyboard navigation, and click handlers). Understanding this option is key to implementing the correct selection behavior for your use case.
347+
348+
### `multiSelect: false` (Single Selection Mode)
349+
When `multiSelect: false`, the grid enforces **strict single selection**:
350+
- **Checkbox Selection**: Clicking a checkbox selects only that row. Clicking a checkbox that's already selected will **deselect** it (toggle behavior). Only one row can be selected at a time.
351+
- **Keyboard Selection**: Using Shift+Arrow keys to extend a range will select only the current row (range is clamped to a single row). Regular arrow navigation moves between rows but doesn't change selection.
352+
- **Overall Behavior**: At most one row is selected at any time. If you programmatically select a row while another is selected, only the new row remains selected.
353+
354+
### `multiSelect: true` (Multiple Selection Mode)
355+
When `multiSelect: true`, the grid allows **multiple rows to be selected**:
356+
- **Checkbox Selection**: Clicking a checkbox adds or removes that row from the selection set. Multiple rows can be checked independently.
357+
- **Keyboard Selection**: Using Shift+Arrow keys extends the selection range to include multiple rows. Ctrl/Cmd+Click or Shift+Click can be used to build complex selections.
358+
- **Overall Behavior**: Multiple rows can be selected and retained in the selection set.
359+
360+
### Selection Methods & `multiSelect`
361+
All row selection methods respect the `multiSelect` option:
362+
1. **Checkbox Selection** (when `enableCheckboxSelector: true`): Respects `multiSelect` setting
363+
2. **Keyboard Selection** (Shift+Arrow): Respects `multiSelect` setting
364+
3. **Programmatic Selection** (calling `setSelectedRows()`): Not restricted by `multiSelect` but subsequent UI interactions will respect it
365+
4. **Other Selection Handlers**: All adhere to the `multiSelect` constraint
366+
367+
`selectionOptions.selectActiveRow` only controls whether activating a row also selects it; it does not override `multiSelect` and cannot enable multiple selection when `multiSelect: false`.
368+
342369
## Troubleshooting
343370
### Adding a Column dynamically is removing the Row Selection column, why is that?
344371
The reason is because the Row Selection (checkbox) plugin is a special column and Slickgrid-Universal is adding an extra column dynamically for the Row Selection checkbox and that is **not** reflected in your local copy of `columns`. To address this issue, you need to get the Slickgrid-Universal internal copy of all columns (including the extra columns), you can get it via `getAllColumnDefinitions()` from the Grid Service and then you can use to that array and that will work.

frameworks/angular-slickgrid/docs/grid-functionalities/composite-editor-modal.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ Mass Update allows you to apply changes (from the modal form) to the entire data
108108
109109
Note however that there is a subtle difference compare to the Create Item action, you need to specifically tag which column will show up in the Mass Update and you need to do that by adding `massUpdate: true` flag inside the `editor` property of each column definition that you wish to be included in the form.
110110
111+
Important: `selectionOptions.selectActiveRow: false` is commonly used for checkbox-based multi-row workflows, but you must also keep `multiSelect` enabled (default `true`), otherwise `mass-selection` and `auto-mass` will not work as expected because only one row can stay selected at a time.
112+
111113
`auto-mass` option: If you decide to use Mass Update and Mass Selection and wish to only expose 1 button to do the action and let the system decide if it's doing a Mass Update or a Mass Selection change, you can use the modal type `auto-mass` (if it detect that some rows are selected it will use Mass Selection or else Mass Update). From our experience, user prefer to expose the 2 separate action buttons (less confusion), but this for you to decide, you have the option.
112114
113115
##### with TypeScript
@@ -166,6 +168,8 @@ example class MyCompositeDemo {
166168
## Mass Selection
167169
Similar to the Mass Update but apply changes only on the selected rows. The setup is nearly identical to the Mass Update, just make sure to display appropriate modal title. Also note that you also need to add `massUpdate: true` flag inside the `editor` property of each column definition that you wish to be included in the Mass Selection changes form.
168170
171+
**Important**: Mass Selection requires real multi-row selection, so even if you use `selectionOptions.selectActiveRow: false`, you must keep `multiSelect` enabled (default `true`); with `multiSelect: false`, only one row can remain selected and the modal will not behave as expected.
172+
169173
Refer to the [Mass Update](#mass-update) section for code sample.
170174
171175
`auto-mass` option: If you decide to use Mass Update and Mass Selection and wish to only expose 1 button to do the action and let the system decide if it's doing a Mass Update or a Mass Selection change, you can use the modal type `auto-mass` (if it detect that some rows are selected it will use Mass Selection or else Mass Update). From our experience, user prefer to expose the 2 separate action buttons (less confusion), but this for you to decide, you have the option.

frameworks/angular-slickgrid/docs/grid-functionalities/row-selection.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [Disable Custom Rows Selections via `selectableOverride`](#disable-custom-rows-selections-via-selectableoverride)
77
- [Disable External Button when having Empty Selection](#disable-external-button-when-having-empty-selection)
88
- [Change Row Selections](#change-row-selections)
9+
- [Understanding the multiSelect Option](#understanding-the-multiselect-option)
910
- Troubleshooting
1011
- [Adding a Column dynamically is removing the Row Selection column, why is that?](#adding-a-column-dynamically-is-removing-the-row-selection-column-why-is-that)
1112
- [Hybrid Selection Model (cell+row selection)](#hybrid-selection-model-and-drag-fill)
@@ -54,7 +55,7 @@ onSelectedRowsChanged(e, args) {
5455
```
5556

5657
## Multiple Row Selections
57-
As for multiple row selections, you need to provide an extra grid option of `rowSelectionOptions` which is an object and within it, you need to disable the `selectActiveRow` flag. The other configurations are the same as a Single Selection, which is to enable `enableCheckboxSelector` and `enableSelection` (or `enableRowSelection` in <=9.x). Then as describe earlier, you will subscribe to `onSelectedRowsChanged` (for that you need to bind to `(gridChanged)`).
58+
As for multiple row selections, you need to provide `selectionOptions.selectActiveRow: false` and keep `multiSelect` enabled (default is `true`). The other configurations are the same as a Single Selection, which is to enable `enableCheckboxSelector` and `enableSelection` (or `enableRowSelection` in <=9.x). Then as describe earlier, you will subscribe to `onSelectedRowsChanged` (for that you need to bind to `(gridChanged)`).
5859

5960
#### View
6061
```html
@@ -83,6 +84,7 @@ export class Example1 implements OnInit {
8384
// True (Single Selection), False (Multiple Selections)
8485
selectActiveRow: false
8586
},
87+
// keep `multiSelect` enabled (default) for actual multiple row selection
8688
}
8789
}
8890

@@ -295,6 +297,28 @@ copyDraggedCellRange(args: OnDragReplaceCellsEventArgs) {
295297
}
296298
```
297299

300+
## Understanding the `multiSelect` Option
301+
The `multiSelect` grid option is a critical setting that controls how row selection works across all selection methods (checkboxes, keyboard navigation, and click handlers). Understanding this option is key to implementing the correct selection behavior for your use case.
302+
303+
### `multiSelect: false` (Single Selection Mode)
304+
When `multiSelect: false`, the grid enforces **strict single selection**:
305+
- **Checkbox Selection**: Clicking a checkbox selects only that row. Clicking a checkbox that's already selected will **deselect** it (toggle behavior). Only one row can be selected at a time.
306+
- **Keyboard Selection**: Using Shift+Arrow keys to extend a range will select only the current row (range is clamped to a single row). Regular arrow navigation moves between rows but doesn't change selection.
307+
- **Overall Behavior**: At most one row is selected at any time. If you programmatically select a row while another is selected, only the new row remains selected.
308+
309+
### `multiSelect: true` (Multiple Selection Mode)
310+
When `multiSelect: true`, the grid allows **multiple rows to be selected**:
311+
- **Checkbox Selection**: Clicking a checkbox adds or removes that row from the selection set. Multiple rows can be checked independently.
312+
- **Keyboard Selection**: Using Shift+Arrow keys extends the selection range to include multiple rows. Ctrl/Cmd+Click or Shift+Click can be used to build complex selections.
313+
- **Overall Behavior**: Multiple rows can be selected and retained in the selection set.
314+
315+
### Selection Methods & `multiSelect`
316+
All row selection methods respect the `multiSelect` option:
317+
1. **Checkbox Selection** (when `enableCheckboxSelector: true`): Respects `multiSelect` setting
318+
2. **Keyboard Selection** (Shift+Arrow): Respects `multiSelect` setting
319+
3. **Programmatic Selection** (calling `setSelectedRows()`): Not restricted by `multiSelect` but subsequent UI interactions will respect it
320+
4. **Other Selection Handlers**: All adhere to the `multiSelect` constraint
321+
298322
## Troubleshooting
299323
### Adding a Column dynamically is removing the Row Selection column, why is that?
300324
The reason is because the Row Selection (checkbox) plugin is a special column and Angular-Slickgrid is adding an extra column dynamically for the Row Selection checkbox and that is **not** reflected in your local copy of `columns`. To address this issue, you need to get the Angular-Slickgrid internal copy of all columns (including the extra columns), you can get it via `getAllColumnDefinitions()` from the Grid Service and then you can use to that array and that will work.

frameworks/angular-slickgrid/src/demos/examples/example30.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,6 @@ export class Example30Component implements OnDestroy, OnInit {
504504
preHeaderPanelHeight: 28,
505505
enableCheckboxSelector: true,
506506
enableSelection: true,
507-
multiSelect: false,
508507
checkboxSelector: {
509508
hideInFilterHeaderRow: false,
510509
hideInColumnTitleRow: true,

frameworks/aurelia-slickgrid/docs/grid-functionalities/composite-editor-modal.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ Mass Update allows you to apply changes (from the modal form) to the entire data
108108
109109
Note however that there is a subtle difference compare to the Create Item action, you need to specifically tag which column will show up in the Mass Update and you need to do that by adding `massUpdate: true` flag inside the `editor` property of each column definition that you wish to be included in the form.
110110
111+
Important: `selectionOptions.selectActiveRow: false` is commonly used for checkbox-based multi-row workflows, but you must also keep `multiSelect` enabled (default `true`), otherwise `mass-selection` and `auto-mass` will not work as expected because only one row can stay selected at a time.
112+
111113
`auto-mass` option: If you decide to use Mass Update and Mass Selection and wish to only expose 1 button to do the action and let the system decide if it's doing a Mass Update or a Mass Selection change, you can use the modal type `auto-mass` (if it detect that some rows are selected it will use Mass Selection or else Mass Update). From our experience, user prefer to expose the 2 separate action buttons (less confusion), but this for you to decide, you have the option.
112114
113115
##### with TypeScript
@@ -166,6 +168,8 @@ example class MyCompositeDemo {
166168
## Mass Selection
167169
Similar to the Mass Update but apply changes only on the selected rows. The setup is nearly identical to the Mass Update, just make sure to display appropriate modal title. Also note that you also need to add `massUpdate: true` flag inside the `editor` property of each column definition that you wish to be included in the Mass Selection changes form.
168170
171+
**Important**: Mass Selection requires real multi-row selection, so even if you use `selectionOptions.selectActiveRow: false`, you must keep `multiSelect` enabled (default `true`); with `multiSelect: false`, only one row can remain selected and the modal will not behave as expected.
172+
169173
Refer to the [Mass Update](#mass-update) section for code sample.
170174
171175
`auto-mass` option: If you decide to use Mass Update and Mass Selection and wish to only expose 1 button to do the action and let the system decide if it's doing a Mass Update or a Mass Selection change, you can use the modal type `auto-mass` (if it detect that some rows are selected it will use Mass Selection or else Mass Update). From our experience, user prefer to expose the 2 separate action buttons (less confusion), but this for you to decide, you have the option.

0 commit comments

Comments
 (0)