-
-
Notifications
You must be signed in to change notification settings - Fork 12
Row Selection
- Single Row Selection
- Multiple Row Selections
- Change Dynamically Single/Multiple Selections
- Mixing Single & Multiple Row Selections
- Disable Custom Rows Selections via
selectableOverride
- Disable External Button when having Empty Selection
- Change Row Selections
- Troubleshooting
For row selection, you can simply play with couple of grid options (see below) and subscribe to onSelectedRowsChanged
(a SlickGrid Event that is, it's not an Observable). However please note that onSelectedRowsChanged
is a function available on the Grid
object and you will need bind to (gridChanged)
to get the object when grid is ready. There are 2 types of row selection(s) which you can do.
Note: enableCheckboxSelector
and enableExcelCopyBuffer
do not work well together, this is because they both share the same Row.SelectionModel
and one cancels the other. It is recommended to not use enableExcelCopyBuffer
in that case.
For a single row selection, you need to have enableCellNavigation: true
, enableRowSelection: true
and multiSelect: false
and as described earlier, 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.
You can also do it through a delegate
since all SlickGrid events are exposed as delegate
. For more info see Wiki - OnEvents - 3. delegate
export class Example1 {
defineGrid() {
// define columns
...
// grid options
const gridOptions = {
enableAutoResize: true,
enableCellNavigation: true,
enableCheckboxSelector: true,
enableRowSelection: true,
multiSelect: false,
}
}
handleRowSelection(event, args) {
console.log(event, args);
}
render() {
return (
<SlickgridReact gridId="grid1"
columnDefinitions={this.state.columnDefinitions1}
gridOptions={this.state.gridOptions1!}
dataset={this.state.dataset1}
onReactGridCreated={$event => this.reactGrid1Ready($event.detail)}
onSelectedRowsChanged={$event => this.onGrid1SelectedRowsChanged($event.detail.eventData, $event.detail.args)}
/>
);
}
}
It's preferable to use the with delegate
, but if you really wish, you can also use directly the SlickGrid event that you can subscribe to. However, don't forget to unsubscribe to a SlickGrid event.
const gridOptions = {
enableAutoResize: true,
enableCellNavigation: true,
enableRowSelection: true
}
gridObjChanged(grid) {
grid.onSelectedRowsChanged.subscribe((e, args) => {
if (Array.isArray(args.rows)) {
this.selectedObjects = args.rows.map(idx => {
const item = grid.getDataItem(idx);
return item.title || '';
});
}
});
}
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.
You can also do it through an event since all SlickGrid events are exposed. For more info see Wiki - OnEvents - 3. event
export class Example1 {
defineGrid() {
// define columns
...
// grid options
const gridOptions = {
enableAutoResize: true,
enableCellNavigation: true,
enableCheckboxSelector: true,
enableRowSelection: true,
rowSelectionOptions: {
// True (Single Selection), False (Multiple Selections)
selectActiveRow: false
},
}
}
handleRowSelection(event, args) {
console.log(event, args);
}
render() {
return (
<SlickgridReact gridId="grid1"
columnDefinitions={this.state.columnDefinitions1}
gridOptions={this.state.gridOptions1!}
dataset={this.state.dataset1}
onReactGridCreated={$event => this.reactGrid1Ready($event.detail)}
onSelectedRowsChanged={$event => this.onGrid1SelectedRowsChanged($event.detail.eventData, $event.detail.args)}
/>
);
}
}
It's preferable to use the with delegate
, but if you really wish, you can also use directly the SlickGrid event that you can subscribe to. However, don't forget to unsubscribe to a SlickGrid event.
export class Example1 {
defineGrid() {
const gridOptions = {
enableAutoResize: true,
enableCellNavigation: true,
enableCheckboxSelector: true,
enableRowSelection: true,
rowSelectionOptions: {
// True (Single Selection), False (Multiple Selections)
selectActiveRow: false
},
}
}
gridObjChanged(grid) {
grid.onSelectedRowsChanged.subscribe((e, args) => {
if (Array.isArray(args.rows)) {
this.selectedObjects = args.rows.map(idx => {
const item = grid.getDataItem(idx);
return item.title || '';
});
}
});
}
}
If you want to change from Multiple Selections to Single Selection (and vice-versa), you could toggle the grid options enableCellNavigation
flag (False
when you want Single Selection), however this is not possible when using Inline Editors since this flag is required. Note that there is currently no other ways of toggling dynamically without re-creating the grid.
SlickGrid is so powerful and customizable, you could if you wish mix the multiple row selections (cell column 1) and single row selection (any other cell click). For that though, you will need to use 2 SlickGrid Events (onClick
and onSelectedRowsChanged
). For example with a delegate
we can do it this way:
export class Example1 {
handleMultipleRowSelections(event, args) {
console.log('multiple row checkbox selected', event, args);
}
handleSingleRowClick(event, args) {
console.log('multiple row checkbox selected', event, args);
// when clicking on any cell, we will make it the new selected row
// however, we don't want to interfere with multiple row selection checkbox which is on 1st column cell
if (args.cell !== 0) {
grid.setSelectedRows([args.row]);
}
}
render() {
return (
<SlickgridReact gridId="grid1"
columnDefinitions={this.state.columnDefinitions1}
gridOptions={this.state.gridOptions1!}
dataset={this.state.dataset1}
onReactGridCreated={$event => this.reactGrid1Ready($event.detail)}
onClick={$event => { this.onCellClicked($event.detail.eventData, $event.detail.args); }}
onSelectedRowsChanged={$event => this.onGrid1SelectedRowsChanged($event.detail.eventData, $event.detail.args)}
/>
);
}
}
You can use selectableOverride
to provide custom logic to disable certain rows selections, for example the code below will remove the row selection on every second row.
export class Example1 implements OnInit {
defineGrid() {
const gridOptions = {
enableRowSelection: true,
enableCheckboxSelector: true,
checkboxSelector: {
// you can override the logic for showing (or not) the expand icon
// for example, display the expand icon only on every 2nd row
// selectableOverride: (row: number, dataContext: any, grid: any) => (dataContext.id % 2 === 1)
},
multiSelect: false,
rowSelectionOptions: {
// True (Single Selection), False (Multiple Selections)
selectActiveRow: true,
},
};
}
}
When having an external button that you want to work only when there's row selection, there are 2 ways of doing this.
- use the
onSelectedRowsChanged
event (via your View in HTML or via ViewModel)
isMyButtonDisabled = false;
handleOnSelectedRowsChanged(args) {
this.isMyButtonDisabled = args?.rows?.length === 0;
}
render() {
return (
<SlickgridReact gridId="grid1"
columnDefinitions={this.state.columnDefinitions1}
gridOptions={this.state.gridOptions1!}
dataset={this.state.dataset1}
onReactGridCreated={$event => this.reactGrid1Ready($event.detail)}
onClick={$event => { this.onCellClicked($event.detail.eventData, $event.detail.args); }}
onSelectedRowsChanged={$event => this.handleOnSelectedRowsChanged($event.detail.eventData, $event.detail.args)}
/>
);
}
- use the
onGridStateChanged
event (see Grid State & Presets Wiki)
isMyButtonDisabled = false;
handleOngridStateChanged(gridState) {
if (Array.isArray(gridState?.rowSelection.dataContextIds)) {
this.isMassSelectionDisabled = gridState.rowSelection.dataContextIds.length === 0;
}
}
render() {
return (
<SlickgridReact gridId="grid1"
columnDefinitions={this.state.columnDefinitions1}
gridOptions={this.state.gridOptions1!}
dataset={this.state.dataset1}
onReactGridCreated={$event => this.reactGrid1Ready($event.detail)}
onClick={$event => { this.onCellClicked($event.detail.eventData, $event.detail.args); }}
onGridStateChanged={$event => this.gridStateChanged($event.detail)}
onSelectedRowsChanged={$event => this.handleOngridStateChanged($event.detail.eventData, $event.detail.args)}
/>
);
}
You can change which row(s) are selected by using the built-in SlickGrid method setSelectedRows(rowIndexes)
(passing an empty array will clear all selection), however please note that it requires an array of row indexes as you see them in the UI and it won't work that great with Pagination (if that is what you are looking for then take a look at this Stack Overflow Q&A)
export class Example1 {
reactGrid: SlickgridReactInstance;
reactGridReady(reactGrid: SlickgridReactInstance) {
this.reactGrid = reactGrid;
}
changeRowSelections() {
this.reactGrid.slickGrid.setSelectedRows(rowIndexes);
// OR providing an empty array will clear the row selection
// this.reactGrid.slickGrid.setSelectedRows([]);
}
render() {
return (
<SlickgridReact gridId="grid1"
columnDefinitions={this.state.columnDefinitions1}
gridOptions={this.state.gridOptions1!}
dataset={this.state.dataset1}
onReactGridCreated={$event => this.reactGrid1Ready($event.detail)}
onClick={$event => { this.onCellClicked($event.detail.eventData, $event.detail.args); }}
onSelectedRowsChanged={$event => this.changeRowSelections()}
/>
);
}
}
The reason is because the Row Selection (checkbox) plugin is a special column and slickgrid-react is adding an extra column dynamically for the Row Selection checkbox and that is not reflected in your local copy of columnDefinitions
. To address this issue, you need to get the slickgrid-react 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.
reactGridReady(reactGrid: SlickgridReactInstance) {
this.reactGrid = reactGrid;
}
addNewColumn() {
const newColumn = { /*...*/ };
const allColumns = this.reactGrid.gridService.getAllColumnDefinitions();
allColumns.push(newColumn);
this.columnDefinitions = allColumns.slice(); // or use spread operator [...cols]
// you could also use SlickGrid setColumns() method
// this.reactGrid.slickGrid.setColumns(cols);
}
Contents
- Slickgrid-React Wiki
- Installation
- Styling
- Interfaces/Models
- Column Functionalities
- Global Grid Options
- Localization
- Events
- Grid Functionalities
- Auto-Resize / Resizer Service
- Resize by Cell Content
- Add/Delete/Update or Highlight item
- Dynamically Change Row CSS Classes
- Column Picker
- Composite Editor Modal
- Context Menu
- Custom Tooltip
- Excel Copy Buffer
- Export to Excel
- Export to File (CSV/Txt)
- Grid Menu
- Grid State & Presets
- Grouping & Aggregators
- Header Menu & Header Buttons
- Header Title Grouping
- Pinning (frozen) of Columns/Rows
- Row Colspan
- Row Detail
- Row Selection
- Tree Data Grid
- SlickGrid & DataView objects
- Addons (controls/plugins)
- Backend Services