Selection & Context Menu
Checkbox selection with a filtered-aware select-all; Ctrl/Shift+click also work. Navigate cells with the arrow keys and press Space to select. Right-click a row for the context menu.
selectionMode selectedKeys rowContextMenu keyboard
1.000 rows virtual filterRow
Selected: 0 rows
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeColumn, OgeGrid } from '@oge-ui/grid';
import type { RowKey } from '@oge-ui/core';
import type { OgeContextMenuEvent } from '@oge-ui/grid';
interface Employee {
id: number;
firstName: string;
lastName: string;
}
@Component({
selector: 'demo-root',
imports: [OgeColumn, OgeGrid],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-grid [data]="employees" keyField="id"
selectionMode="checkbox" [(selectedKeys)]="selected"
(rowContextMenu)="onContextMenu($event)">
<oge-column field="firstName" />
<oge-column field="lastName" />
</oge-grid>
`,
})
export class Demo {
readonly employees = [
{ id: 1, firstName: 'Ali', lastName: 'Yılmaz', department: 'Engineering', city: 'İstanbul', salary: 8400, hireDate: '2019-03-11' },
{ id: 2, firstName: 'Ayşe', lastName: 'Kaya', department: 'Sales', city: 'Ankara', salary: 7200, hireDate: '2020-07-02' },
{ id: 3, firstName: 'Mehmet', lastName: 'Demir', department: 'Engineering', city: 'İzmir', salary: 9100, hireDate: '2018-01-23' },
{ id: 4, firstName: 'Zeynep', lastName: 'Şahin', department: 'Finance', city: 'İstanbul', salary: 6800, hireDate: '2021-11-15' },
{ id: 5, firstName: 'Emre', lastName: 'Çelik', department: 'Support', city: 'Bursa', salary: 5400, hireDate: '2022-05-09' },
];
protected readonly selected = signal<RowKey[]>([]);
protected onContextMenu(event: OgeContextMenuEvent<Employee>): void {
// push items to open the built-in menu; leave empty for the browser menu
event.items.push({
text: 'Copy name',
action: () => this.copy(event.row),
});
}
private copy(row: Employee): void {
void navigator.clipboard.writeText(`${row.firstName} ${row.lastName}`);
}
}Deferred selection
With selectionDeferred the grid never materializes a key list — the selection is a serializable FilterExpr in the two-way selectionFilter binding. Select-all over a million remote rows costs nothing: the expression captures the current filter, and unchecking a row just adds an and-not clause. Send the expression to your backend to process the selection server-side.
selectionDeferred selectionFilter
selectionFilter
null (nothing selected)
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeColumn, OgeGrid } from '@oge-ui/grid';
import type { FilterExpr } from '@oge-ui/core';
@Component({
selector: 'demo-root',
imports: [OgeColumn, OgeGrid],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-grid [data]="employees" keyField="id"
selectionMode="checkbox"
[selectionDeferred]="true" [(selectionFilter)]="selectionFilter">
<oge-column field="firstName" />
</oge-grid>
<!-- selectionFilter is a plain FilterExpr — POST it to your backend:
null → nothing selected
{ field: 'id', op: 'isnotnull' } → select-all (no filter active)
{ and: [all, { not: { id eq 42 } }] } → all except #42 -->
`,
})
export class Demo {
readonly employees = [
{ id: 1, firstName: 'Ali', lastName: 'Yılmaz', department: 'Engineering', city: 'İstanbul', salary: 8400, hireDate: '2019-03-11' },
{ id: 2, firstName: 'Ayşe', lastName: 'Kaya', department: 'Sales', city: 'Ankara', salary: 7200, hireDate: '2020-07-02' },
{ id: 3, firstName: 'Mehmet', lastName: 'Demir', department: 'Engineering', city: 'İzmir', salary: 9100, hireDate: '2018-01-23' },
{ id: 4, firstName: 'Zeynep', lastName: 'Şahin', department: 'Finance', city: 'İstanbul', salary: 6800, hireDate: '2021-11-15' },
{ id: 5, firstName: 'Emre', lastName: 'Çelik', department: 'Support', city: 'Bursa', salary: 5400, hireDate: '2022-05-09' },
];
protected readonly selectionFilter = signal<FilterExpr | null>(null);
}Notes
[(selectedKeys)]is a two-way model — push keys in from outside and the checkboxes follow.- Select-all operates on the filtered set: apply a filter first and only matching rows are selected.
selectAllMode="page"restricts it to the visible page. - Shift-ranges span group rows correctly (only data rows are selected).
- Ctrl+C (or
copyToClipboard()) copies the selected rows as tab-separated text ready for Excel. - Full keyboard support: arrows, Home/End, PageUp/PageDown, Space to select — WAI-ARIA grid pattern, verified with axe.