igniteui-angular 21.1.0-rc.4 → 21.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +29 -0
  2. package/fesm2022/igniteui-angular-grids-core.mjs +5 -3
  3. package/fesm2022/igniteui-angular-grids-core.mjs.map +1 -1
  4. package/fesm2022/igniteui-angular-grids-grid.mjs +6 -1
  5. package/fesm2022/igniteui-angular-grids-grid.mjs.map +1 -1
  6. package/fesm2022/igniteui-angular-grids-hierarchical-grid.mjs +1 -0
  7. package/fesm2022/igniteui-angular-grids-hierarchical-grid.mjs.map +1 -1
  8. package/fesm2022/igniteui-angular-grids-lite.mjs +2 -0
  9. package/fesm2022/igniteui-angular-grids-lite.mjs.map +1 -1
  10. package/fesm2022/igniteui-angular-simple-combo.mjs +1 -1
  11. package/fesm2022/igniteui-angular-simple-combo.mjs.map +1 -1
  12. package/lib/core/styles/components/grid/_grid-theme.scss +4 -1
  13. package/migrations/migration-collection.json +7 -0
  14. package/migrations/update-21_1_0_add-agent-skills/index.d.ts +3 -0
  15. package/migrations/update-21_1_0_add-agent-skills/index.js +46 -0
  16. package/package.json +4 -4
  17. package/skills/igniteui-angular-components/SKILL.md +71 -0
  18. package/skills/igniteui-angular-components/references/charts.md +447 -0
  19. package/skills/igniteui-angular-components/references/data-display.md +347 -0
  20. package/skills/igniteui-angular-components/references/directives.md +149 -0
  21. package/skills/igniteui-angular-components/references/feedback.md +141 -0
  22. package/skills/igniteui-angular-components/references/form-controls.md +298 -0
  23. package/skills/igniteui-angular-components/references/layout-manager.md +415 -0
  24. package/skills/igniteui-angular-components/references/layout.md +216 -0
  25. package/skills/igniteui-angular-components/references/setup.md +157 -0
  26. package/skills/igniteui-angular-grids/SKILL.md +110 -0
  27. package/skills/igniteui-angular-grids/references/data-operations.md +436 -0
  28. package/skills/igniteui-angular-grids/references/editing.md +480 -0
  29. package/skills/igniteui-angular-grids/references/features.md +218 -0
  30. package/skills/igniteui-angular-grids/references/paging-remote.md +388 -0
  31. package/skills/igniteui-angular-grids/references/state.md +448 -0
  32. package/skills/igniteui-angular-grids/references/structure.md +290 -0
  33. package/skills/igniteui-angular-grids/references/types.md +428 -0
  34. package/skills/igniteui-angular-theming/SKILL.md +530 -0
  35. package/styles/igniteui-angular-dark.css +1 -1
  36. package/styles/igniteui-angular.css +1 -1
  37. package/styles/igniteui-bootstrap-dark.css +1 -1
  38. package/styles/igniteui-bootstrap-light.css +1 -1
  39. package/styles/igniteui-dark-green.css +1 -1
  40. package/styles/igniteui-fluent-dark-excel.css +1 -1
  41. package/styles/igniteui-fluent-dark-word.css +1 -1
  42. package/styles/igniteui-fluent-dark.css +1 -1
  43. package/styles/igniteui-fluent-light-excel.css +1 -1
  44. package/styles/igniteui-fluent-light-word.css +1 -1
  45. package/styles/igniteui-fluent-light.css +1 -1
  46. package/styles/igniteui-indigo-dark.css +1 -1
  47. package/styles/igniteui-indigo-light.css +1 -1
  48. package/styles/maps/igniteui-angular-dark.css.map +1 -1
  49. package/styles/maps/igniteui-angular.css.map +1 -1
  50. package/styles/maps/igniteui-bootstrap-dark.css.map +1 -1
  51. package/styles/maps/igniteui-bootstrap-light.css.map +1 -1
  52. package/styles/maps/igniteui-dark-green.css.map +1 -1
  53. package/styles/maps/igniteui-fluent-dark-excel.css.map +1 -1
  54. package/styles/maps/igniteui-fluent-dark-word.css.map +1 -1
  55. package/styles/maps/igniteui-fluent-dark.css.map +1 -1
  56. package/styles/maps/igniteui-fluent-light-excel.css.map +1 -1
  57. package/styles/maps/igniteui-fluent-light-word.css.map +1 -1
  58. package/styles/maps/igniteui-fluent-light.css.map +1 -1
  59. package/styles/maps/igniteui-indigo-dark.css.map +1 -1
  60. package/styles/maps/igniteui-indigo-light.css.map +1 -1
  61. package/types/igniteui-angular-grids-lite.d.ts +2 -0
@@ -0,0 +1,480 @@
1
+ # Grid Editing — Cell Editing, Row Editing, Batch Editing & Validation
2
+
3
+ > **Part of the [`igniteui-angular-grids`](../SKILL.md) skill hub.**
4
+ > For grid import patterns and `viewChild` access — see [`data-operations.md`](./data-operations.md).
5
+ > For state persistence — see [`state.md`](./state.md).
6
+ > For paging and remote data — see [`paging-remote.md`](./paging-remote.md).
7
+
8
+ ## Editing Data Through the Grid
9
+
10
+ > **AGENT INSTRUCTION:** When a user says they want to "edit data through the grid", "make the grid editable", or "allow CRUD in the grid", use this section to pick the right editing mode before writing any code.
11
+
12
+ ### Choosing an Editing Mode
13
+
14
+ | Mode | When to use | Key properties |
15
+ |---|---|---|
16
+ | **Cell editing** | Each cell saves immediately when the user confirms or leaves it. Good for quick single-field corrections. | `[editable]="true"` on columns + `(cellEditDone)` |
17
+ | **Row editing** | User edits multiple cells in a row and confirms/cancels the whole row at once. **Best for most CRUD UIs.** | `[rowEditable]="true"` + `[editable]="true"` on columns + `(rowEditDone)` |
18
+ | **Batch editing** | Accumulate many changes across multiple rows with undo/redo, then commit or discard all at once. | `[batchEditing]="true"` + `[rowEditable]="true"` |
19
+
20
+ > **Default recommendation:** use **row editing** for most data management UIs (e.g., "edit available cars"). It prevents half-edited data from being visible and gives users a clear Done/Cancel flow per row.
21
+
22
+ ### Cell Editing (Immediate)
23
+
24
+ > **Docs:** [Cell Editing](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/cell-editing)
25
+
26
+ The simplest mode. Each cell saves the moment the user tabs away or presses Enter.
27
+
28
+ ```typescript
29
+ import { Component, ChangeDetectionStrategy, signal, viewChild, inject } from '@angular/core';
30
+ import { IgxGridComponent, IGX_GRID_DIRECTIVES } from 'igniteui-angular/grids/grid';
31
+ import { IGridEditDoneEventArgs } from 'igniteui-angular/grids/core';
32
+
33
+ @Component({
34
+ selector: 'app-cars-grid',
35
+ imports: [IGX_GRID_DIRECTIVES],
36
+ templateUrl: './cars-grid.component.html',
37
+ changeDetection: ChangeDetectionStrategy.OnPush
38
+ })
39
+ export class CarsGridComponent {
40
+ gridRef = viewChild.required<IgxGridComponent>('grid');
41
+ private carService = inject(CarService);
42
+ protected cars = signal<Car[]>([]);
43
+
44
+ constructor() {
45
+ this.carService.getCars().subscribe(data => this.cars.set(data));
46
+ }
47
+
48
+ onCellEditDone(event: IGridEditDoneEventArgs) {
49
+ // Persist the single-cell change immediately
50
+ const updatedCar = { ...event.rowData, [event.column.field]: event.newValue };
51
+ this.carService.updateCar(updatedCar).subscribe();
52
+ }
53
+ }
54
+ ```
55
+
56
+ ```html
57
+ <igx-grid #grid
58
+ [data]="cars()"
59
+ [primaryKey]="'id'"
60
+ [autoGenerate]="false"
61
+ (cellEditDone)="onCellEditDone($event)"
62
+ height="600px">
63
+ <igx-column field="make" header="Make" [editable]="true" [sortable]="true"></igx-column>
64
+ <igx-column field="model" header="Model" [editable]="true" [sortable]="true"></igx-column>
65
+ <igx-column field="year" header="Year" dataType="number" [editable]="true" [sortable]="true"></igx-column>
66
+ <igx-column field="price" header="Price" dataType="number" [editable]="true" [sortable]="true"></igx-column>
67
+ <igx-column field="available" header="Available" dataType="boolean" [editable]="true"></igx-column>
68
+ </igx-grid>
69
+ ```
70
+
71
+ ### Row Editing (Recommended for CRUD)
72
+
73
+ > **Docs:** [Row Editing](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/row-editing)
74
+
75
+ Users click into a row, edit cells, then click **Done** or **Cancel** — changes only apply when Done is pressed. An overlay toolbar appears automatically.
76
+
77
+ ```typescript
78
+ import { Component, ChangeDetectionStrategy, signal, viewChild, inject } from '@angular/core';
79
+ import { IgxGridComponent, IGX_GRID_DIRECTIVES } from 'igniteui-angular/grids/grid';
80
+ import { IGridEditDoneEventArgs, IGridEditEventArgs, IRowDataEventArgs } from 'igniteui-angular/grids/core';
81
+
82
+ @Component({
83
+ selector: 'app-cars-grid',
84
+ imports: [IGX_GRID_DIRECTIVES],
85
+ templateUrl: './cars-grid.component.html',
86
+ changeDetection: ChangeDetectionStrategy.OnPush
87
+ })
88
+ export class CarsGridComponent {
89
+ gridRef = viewChild.required<IgxGridComponent>('grid');
90
+ private carService = inject(CarService);
91
+ protected cars = signal<Car[]>([]);
92
+
93
+ constructor() {
94
+ this.carService.getCars().subscribe(data => this.cars.set(data));
95
+ }
96
+
97
+ onRowEditDone(event: IGridEditDoneEventArgs) {
98
+ // event.newValue contains the full updated row object
99
+ this.carService.updateCar(event.newValue).subscribe();
100
+ }
101
+
102
+ onRowAdded(event: IRowDataEventArgs) {
103
+ // Persist the newly added row; optionally replace local data with server response
104
+ this.carService.createCar(event.data).subscribe(created => {
105
+ this.cars.update(cars => cars.map(c => c === event.data ? created : c));
106
+ });
107
+ }
108
+
109
+ onRowDeleted(event: IRowDataEventArgs) {
110
+ this.carService.deleteCar(event.data.id).subscribe();
111
+ }
112
+
113
+ addCar() {
114
+ // Programmatically start a new row at the end
115
+ this.gridRef().beginAddRowByIndex(this.cars().length);
116
+ }
117
+
118
+ deleteCar(carId: number) {
119
+ this.gridRef().deleteRow(carId);
120
+ }
121
+ }
122
+ ```
123
+
124
+ ```html
125
+ <igx-grid #grid
126
+ [data]="cars()"
127
+ [primaryKey]="'id'"
128
+ [autoGenerate]="false"
129
+ [rowEditable]="true"
130
+ (rowEditDone)="onRowEditDone($event)"
131
+ (rowAdded)="onRowAdded($event)"
132
+ (rowDeleted)="onRowDeleted($event)"
133
+ height="600px">
134
+
135
+ <igx-column field="make" header="Make" [editable]="true" [sortable]="true"></igx-column>
136
+ <igx-column field="model" header="Model" [editable]="true" [sortable]="true"></igx-column>
137
+ <igx-column field="year" header="Year" dataType="number" [editable]="true" [sortable]="true"></igx-column>
138
+ <igx-column field="price" header="Price" dataType="number" [editable]="true" [sortable]="true"></igx-column>
139
+ <igx-column field="available" header="Available" dataType="boolean" [editable]="true"></igx-column>
140
+
141
+ <!-- Action strip: shows Edit and Delete buttons on row hover; Add Row button in toolbar -->
142
+ <igx-action-strip>
143
+ <igx-grid-editing-actions [addRow]="true"></igx-grid-editing-actions>
144
+ </igx-action-strip>
145
+ </igx-grid>
146
+
147
+ <button (click)="addCar()">Add Car</button>
148
+ ```
149
+
150
+ > **Key inputs summary:**
151
+ > - `[rowEditable]="true"` — enables the Done/Cancel overlay per row
152
+ > - `[editable]="true"` on each `igx-column` — marks which fields the user can change
153
+ > - `[primaryKey]` — **required** for editing to work
154
+ > - `[autoGenerate]="false"` — always define columns explicitly when editing is enabled so you control which fields are editable
155
+ > - `<igx-action-strip>` with `<igx-grid-editing-actions>` — adds hover Edit/Delete buttons and an optional Add Row button automatically
156
+
157
+ ### Programmatic Row Adding with Default Values
158
+
159
+ When starting a new row programmatically, pre-populate fields using `(cellEditEnter)` on the new row:
160
+
161
+ ```typescript
162
+ onCellEditEnter(event: IGridEditEventArgs) {
163
+ if (event.isAddRow && event.column.field === 'available') {
164
+ event.cellEditArgs.newValue = true; // default new cars to available
165
+ }
166
+ if (event.isAddRow && event.column.field === 'year') {
167
+ event.cellEditArgs.newValue = new Date().getFullYear();
168
+ }
169
+ }
170
+ ```
171
+
172
+ ```html
173
+ <igx-grid #grid ... (cellEditEnter)="onCellEditEnter($event)">
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Batch Editing & Transactions
179
+
180
+ > **Docs:** [Batch Editing](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/batch-editing) (substitute URL prefix per grid type)
181
+
182
+ > **Applies to**: Flat Grid, Tree Grid, and Hierarchical Grid. **Pivot Grid does NOT support batch editing.**
183
+ > Use batch editing when users need to **edit many rows at once** and commit or discard all changes together, with undo/redo support.
184
+
185
+ ### Enabling Batch Editing
186
+
187
+ ```html
188
+ <igx-grid #grid
189
+ [data]="data()"
190
+ [primaryKey]="'id'"
191
+ [batchEditing]="true"
192
+ [rowEditable]="true"
193
+ height="600px">
194
+ <igx-column field="name" [editable]="true"></igx-column>
195
+ <igx-column field="price" dataType="number" [editable]="true"></igx-column>
196
+ <igx-column field="quantity" dataType="number" [editable]="true"></igx-column>
197
+ </igx-grid>
198
+
199
+ <button (click)="commitChanges()">Save All</button>
200
+ <button (click)="undoLast()">Undo</button>
201
+ <button (click)="redoLast()">Redo</button>
202
+ <button (click)="discardAll()">Discard</button>
203
+ ```
204
+
205
+ ### Managing Transactions
206
+
207
+ ```typescript
208
+ commitChanges() {
209
+ // Exit any active edit before committing
210
+ this.gridRef().endEdit(true);
211
+ this.gridRef().transactions.commit(this.gridRef().data);
212
+ }
213
+
214
+ undoLast() {
215
+ // Must exit edit mode before undo/redo
216
+ this.gridRef().endEdit(true);
217
+ this.gridRef().transactions.undo();
218
+ }
219
+
220
+ redoLast() {
221
+ this.gridRef().endEdit(true);
222
+ this.gridRef().transactions.redo();
223
+ }
224
+
225
+ discardAll() {
226
+ this.gridRef().endEdit(false);
227
+ this.gridRef().transactions.clear();
228
+ }
229
+ ```
230
+
231
+ Use `canUndo` and `canRedo` to control button state:
232
+
233
+ ```html
234
+ <button (click)="commitChanges()" [disabled]="gridRef().transactions.getAggregatedChanges(false).length < 1">Save All</button>
235
+ <button (click)="undoLast()" [disabled]="!gridRef().transactions.canUndo">Undo</button>
236
+ <button (click)="redoLast()" [disabled]="!gridRef().transactions.canRedo">Redo</button>
237
+ <button (click)="discardAll()">Discard</button>
238
+ ```
239
+
240
+ ### Transaction State
241
+
242
+ ```typescript
243
+ // Check if there are pending changes
244
+ const hasPendingChanges = this.gridRef().transactions.getAggregatedChanges(false).length > 0;
245
+
246
+ // Get all pending transactions
247
+ const pending = this.gridRef().transactions.getAggregatedChanges(true);
248
+ // Each transaction has: { id, type ('add'|'update'|'delete'), newValue }
249
+ ```
250
+
251
+ ### Sending Batch Changes to Server
252
+
253
+ ```typescript
254
+ saveToServer() {
255
+ const changes = this.gridRef().transactions.getAggregatedChanges(true);
256
+
257
+ const adds = changes.filter(t => t.type === 'add').map(t => t.newValue);
258
+ const updates = changes.filter(t => t.type === 'update').map(t => ({ id: t.id, ...t.newValue }));
259
+ const deletes = changes.filter(t => t.type === 'delete').map(t => t.id);
260
+
261
+ this.dataService.saveBatch({ adds, updates, deletes }).subscribe(() => {
262
+ this.gridRef().transactions.commit(this.gridRef().data);
263
+ this.gridRef().transactions.clear();
264
+ });
265
+ }
266
+ ```
267
+
268
+ ## Excel-Style Editing Workflows
269
+
270
+ ### Inline Cell Editing with Validation
271
+
272
+ ```html
273
+ <igx-grid #grid
274
+ [data]="data()"
275
+ [primaryKey]="'id'"
276
+ [batchEditing]="true"
277
+ (cellEditDone)="onCellEditDone($event)">
278
+
279
+ <igx-column field="name" [editable]="true" required></igx-column>
280
+ <igx-column field="email" [editable]="true" [validators]="emailValidators"></igx-column>
281
+ <igx-column field="quantity" dataType="number" [editable]="true" [validators]="quantityValidators"></igx-column>
282
+ </igx-grid>
283
+ ```
284
+
285
+ ```typescript
286
+ import { Validators } from '@angular/forms';
287
+
288
+ emailValidators = [Validators.required, Validators.email];
289
+ quantityValidators = [Validators.required, Validators.min(0), Validators.max(9999)];
290
+
291
+ onCellEditDone(event: IGridEditDoneEventArgs) {
292
+ // React to edits — e.g., recalculate totals
293
+ if (event.column.field === 'quantity' || event.column.field === 'unitPrice') {
294
+ this.recalculateRowTotal(event.rowID);
295
+ }
296
+ }
297
+ ```
298
+
299
+ ### Clipboard Paste for Bulk Edit
300
+
301
+ Grids support paste from Excel/spreadsheets by default. Configure clipboard behavior:
302
+
303
+ ```html
304
+ <igx-grid #grid
305
+ [data]="data()"
306
+ [primaryKey]="'id'"
307
+ [batchEditing]="true"
308
+ [clipboardOptions]="{ enabled: true, copyHeaders: true, copyFormatters: true, separator: '\t' }">
309
+ </igx-grid>
310
+ ```
311
+
312
+ ### Row Adding via UI
313
+
314
+ ```typescript
315
+ // Flat Grid / Hierarchical Grid:
316
+ this.gridRef().beginAddRowByIndex(0); // at top
317
+ this.gridRef().beginAddRowById('ALFKI'); // under a specific row
318
+ this.gridRef().beginAddRowByIndex(this.gridRef().data.length); // at end
319
+
320
+ // Tree Grid — add as child of a parent:
321
+ this.treeGridRef().addRow(newRowData, parentRowID); // add row as child of parentRowID
322
+ this.treeGridRef().beginAddRowByIndex(3, true); // add as child of row at index 3
323
+ ```
324
+
325
+ Use with Action Strip for visual add/edit actions:
326
+
327
+ ```html
328
+ <igx-grid #grid [data]="data()" [primaryKey]="'id'" [rowEditable]="true">
329
+ <igx-action-strip>
330
+ <igx-grid-editing-actions [addRow]="true"></igx-grid-editing-actions>
331
+ </igx-action-strip>
332
+ <igx-column field="name" [editable]="true"></igx-column>
333
+ </igx-grid>
334
+ ```
335
+
336
+ ## Editing Events Reference
337
+
338
+ All grids fire a consistent sequence of events during cell and row editing:
339
+
340
+ | Event | Fires When | Cancelable |
341
+ |---|---|---|
342
+ | `(rowEditEnter)` | Row enters edit mode | Yes |
343
+ | `(cellEditEnter)` | Cell enters edit mode (after `rowEditEnter`) | Yes |
344
+ | `(cellEdit)` | Cell value is about to be committed | Yes |
345
+ | `(cellEditDone)` | Cell value has been committed | No |
346
+ | `(cellEditExit)` | Cell exits edit mode | No |
347
+ | `(rowEdit)` | Row edit is about to be committed (Done button) | Yes |
348
+ | `(rowEditDone)` | Row edit has been committed | No |
349
+ | `(rowEditExit)` | Row exits edit mode | No |
350
+
351
+ Canceling `(cellEdit)` keeps the cell in edit mode — the value won't commit until Cancel is clicked:
352
+
353
+ ```typescript
354
+ onCellEdit(event: IGridEditEventArgs) {
355
+ if (!event.valid) {
356
+ event.cancel = true; // prevent committing invalid values
357
+ }
358
+ }
359
+ ```
360
+
361
+ ## Validation
362
+
363
+ > **Docs:** [Validation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/validation)
364
+
365
+ ### Template-Driven Validation
366
+
367
+ Apply Angular validators directly on columns:
368
+
369
+ ```html
370
+ <igx-column field="email" [editable]="true" required email></igx-column>
371
+ <igx-column field="age" dataType="number" [editable]="true" required [min]="18" [max]="120"></igx-column>
372
+ ```
373
+
374
+ Supported built-in validators: `required`, `min`, `max`, `email`, `minlength`, `maxlength`, `pattern`.
375
+
376
+ ### Reactive Form Validation
377
+
378
+ Use the `formGroupCreated` event to add custom validators when a row enters edit mode:
379
+
380
+ ```html
381
+ <igx-grid #grid [data]="data()" [rowEditable]="true" [primaryKey]="'id'"
382
+ (formGroupCreated)="onFormGroupCreated($event)">
383
+ </igx-grid>
384
+ ```
385
+
386
+ ```typescript
387
+ onFormGroupCreated(event: IGridFormGroupCreatedEventArgs) {
388
+ const { formGroup } = event;
389
+ formGroup.get('endDate')?.addValidators(this.dateAfterValidator('startDate'));
390
+ }
391
+ ```
392
+
393
+ ### Validation Service
394
+
395
+ The grid exposes a `validation` service:
396
+
397
+ ```typescript
398
+ // Check if the grid is in a valid state
399
+ const isValid = this.gridRef().validation.valid;
400
+
401
+ // Get all records with validation errors
402
+ const invalid = this.gridRef().validation.getInvalid();
403
+
404
+ // Clear validation state for a specific record (or all if no id)
405
+ this.gridRef().validation.clear(recordId);
406
+ ```
407
+
408
+ ## Summaries
409
+
410
+ > **Docs:** [Summaries](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/summaries) (substitute URL prefix per grid type)
411
+
412
+ ### Built-In Summaries
413
+
414
+ ```html
415
+ <igx-column field="amount" dataType="number" [hasSummary]="true"></igx-column>
416
+ ```
417
+
418
+ Default summaries by type:
419
+ - **number**: Count, Min, Max, Sum, Average
420
+ - **date**: Count, Earliest, Latest
421
+ - **string/boolean**: Count
422
+
423
+ ### Custom Summary Operand
424
+
425
+ ```typescript
426
+ import { IgxNumberSummaryOperand, IgxSummaryResult } from 'igniteui-angular/grids/core';
427
+
428
+ class RevenueSummary extends IgxNumberSummaryOperand {
429
+ operate(data: number[]): IgxSummaryResult[] {
430
+ const result = super.operate(data);
431
+ result.push({
432
+ key: 'margin',
433
+ label: 'Avg Margin',
434
+ summaryResult: data.length ? data.reduce((a, b) => a + b, 0) / data.length * 0.15 : 0
435
+ });
436
+ return result;
437
+ }
438
+ }
439
+
440
+ // Use in component
441
+ revenueSummary = RevenueSummary;
442
+ ```
443
+
444
+ ```html
445
+ <igx-column field="revenue" dataType="number" [hasSummary]="true" [summaries]="revenueSummary"></igx-column>
446
+ ```
447
+
448
+ ### Summaries with Grouping
449
+
450
+ When grouping is enabled, summaries appear for each group. Control this with:
451
+
452
+ ```html
453
+ <igx-grid #grid
454
+ [data]="data()"
455
+ [showSummaryOnCollapse]="true"
456
+ [summaryCalculationMode]="'childLevelsOnly'"
457
+ [summaryPosition]="'bottom'">
458
+ </igx-grid>
459
+ ```
460
+
461
+ ## Key Rules
462
+
463
+ 1. **Choose the right editing mode** — cell editing (`[editable]` + `(cellEditDone)`) for immediate per-cell saves; row editing (`[rowEditable]="true"` + `(rowEditDone)`) for confirm/cancel per row (**recommended default for CRUD**); batch editing (`[batchEditing]="true"`) for accumulate-then-commit with undo/redo
464
+ 2. **`[primaryKey]` is required for all editing** — row editing, batch editing, row adding, and row deletion all depend on it (Flat, Tree, Hierarchical, Pivot grids; NOT Grid Lite)
465
+ 3. **Always set `[autoGenerate]="false"` when editing** — define columns explicitly and mark each with `[editable]="true"` to control exactly what users can change
466
+ 4. **Batch editing requires `[primaryKey]`** — call `endEdit(true)` before `transactions.undo()`/`redo()`, commit via `transactions.commit(data)`
467
+ 5. **Cancelable events** — use `event.cancel = true` in `(cellEdit)`, `(rowEdit)`, `(paging)` to prevent the action
468
+ 6. **Validation** — use template-driven validators on columns (`required`, `min`, `max`, `email`, `pattern`) or reactive validators via `(formGroupCreated)`
469
+ 7. **Use the correct component type for `viewChild`** — `IgxGridComponent`, `IgxTreeGridComponent`, `IgxHierarchicalGridComponent`, or `IgxPivotGridComponent`
470
+ 8. **Import the correct directives/components** — `IGX_GRID_DIRECTIVES`, `IGX_TREE_GRID_DIRECTIVES`, `IGX_HIERARCHICAL_GRID_DIRECTIVES`, or `IGX_PIVOT_GRID_DIRECTIVES`
471
+ 9. **Use signals for data** — `[data]="myData()"` with `signal<T[]>([])`
472
+
473
+ ## See Also
474
+
475
+ - [`data-operations.md`](./data-operations.md) — Sorting, filtering, grouping, and canonical grid import patterns
476
+ - [`paging-remote.md`](./paging-remote.md) — Paging, remote data operations, virtualization
477
+ - [`state.md`](./state.md) — State persistence, Tree Grid / Hierarchical Grid / Pivot Grid / Grid Lite data operations
478
+ - [`structure.md`](./structure.md) — Grid structure, column configuration, templates, layout, selection
479
+ - [`../../igniteui-angular-components/SKILL.md`](../../igniteui-angular-components/SKILL.md) — Non-grid Ignite UI components
480
+ - [`../../igniteui-angular-theming/SKILL.md`](../../igniteui-angular-theming/SKILL.md) — Theming & Styling
@@ -0,0 +1,218 @@
1
+ # Grid Features — Grouping, Summaries, Toolbar, Export, Row Drag & More
2
+
3
+ > **Part of the [`igniteui-angular-grids`](../SKILL.md) skill hub.**
4
+ > For grid setup, column config, sorting, filtering, selection — see [`structure.md`](./structure.md).
5
+ > For Tree Grid, Hierarchical Grid, Grid Lite, Pivot Grid specifics — see [`types.md`](./types.md).
6
+ > For full editing coverage (cell/row/batch) — see [`editing.md`](./editing.md).
7
+
8
+ ## Editing
9
+
10
+ > **Full editing coverage is in [`editing.md`](./editing.md)**, which includes cell editing, row editing, batch editing with transactions, row adding/deleting, validation, and summaries. Use that reference for any editing task.
11
+
12
+ Quick reference:
13
+
14
+ | Mode | Key properties |
15
+ |---|---|
16
+ | **Cell editing** | `[editable]="true"` on columns + `(cellEditDone)` |
17
+ | **Row editing** (recommended default) | `[rowEditable]="true"` + `[editable]="true"` on columns + `(rowEditDone)` |
18
+ | **Batch editing** | `[batchEditing]="true"` + `[rowEditable]="true"` + `transactions.commit(data)` |
19
+
20
+ ## Grouping (Grid only)
21
+
22
+ > **Docs:** [Group By](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/groupby)
23
+
24
+ ```html
25
+ <igx-grid [data]="data()" [groupsExpanded]="true">
26
+ <igx-column field="category" [groupable]="true"></igx-column>
27
+
28
+ <!-- Custom group row template -->
29
+ <ng-template igxGroupByRow let-groupRow>
30
+ {{ groupRow.expression.fieldName }}: {{ groupRow.value }} ({{ groupRow.records.length }} items)
31
+ </ng-template>
32
+ </igx-grid>
33
+ ```
34
+
35
+ Programmatic:
36
+
37
+ ```typescript
38
+ this.gridRef().groupBy({ fieldName: 'category', dir: SortingDirection.Asc });
39
+ this.gridRef().clearGrouping('category');
40
+ ```
41
+
42
+ For advanced programmatic grouping patterns — see [`data-operations.md`](./data-operations.md).
43
+
44
+ ## Summaries
45
+
46
+ > **Full summaries coverage (built-in and custom summary operands) is in [`editing.md`](./editing.md).**
47
+
48
+ Quick reference — enable per-column summaries:
49
+
50
+ ```html
51
+ <igx-column field="salary" dataType="number" [hasSummary]="true"></igx-column>
52
+ ```
53
+
54
+ Default summaries by type: **number** → Count/Min/Max/Sum/Average; **date** → Count/Earliest/Latest; **string/boolean** → Count.
55
+
56
+ ## Cell Merging
57
+
58
+ Merge adjacent cells with equal values:
59
+
60
+ ```html
61
+ <igx-column field="category" [merge]="true"></igx-column>
62
+ ```
63
+
64
+ Or apply a custom merge strategy:
65
+
66
+ ```html
67
+ <igx-column field="price" [merge]="true" [mergeStrategy]="priceRangeMerge"></igx-column>
68
+ ```
69
+
70
+ ```typescript
71
+ priceRangeMerge: IgxCellMergeStrategy = {
72
+ shouldMerge(prevCell, curCell) {
73
+ return Math.abs(prevCell.value - curCell.value) < 10;
74
+ }
75
+ };
76
+ ```
77
+
78
+ ## Toolbar
79
+
80
+ > **Docs:** [Toolbar](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/toolbar)
81
+
82
+ ```html
83
+ <igx-grid [data]="data()">
84
+ <igx-grid-toolbar>
85
+ <igx-grid-toolbar-title>Products</igx-grid-toolbar-title>
86
+ <igx-grid-toolbar-actions>
87
+ <igx-grid-toolbar-hiding></igx-grid-toolbar-hiding>
88
+ <igx-grid-toolbar-pinning></igx-grid-toolbar-pinning>
89
+ <igx-grid-toolbar-exporter></igx-grid-toolbar-exporter>
90
+ <igx-grid-toolbar-advanced-filtering></igx-grid-toolbar-advanced-filtering>
91
+ </igx-grid-toolbar-actions>
92
+ </igx-grid-toolbar>
93
+
94
+ <igx-column field="name"></igx-column>
95
+ </igx-grid>
96
+ ```
97
+
98
+ ## Export
99
+
100
+ ### Excel Export
101
+
102
+ > **Docs:** [Excel Export](https://www.infragistics.com/products/ignite-ui-angular/angular/components/exporter-excel)
103
+
104
+ ```typescript
105
+ import { IgxExcelExporterService, IgxExcelExporterOptions } from 'igniteui-angular/grids/core';
106
+
107
+ export class MyComponent {
108
+ private excelExporter = inject(IgxExcelExporterService);
109
+
110
+ exportToExcel() {
111
+ this.excelExporter.exportData(this.data(), new IgxExcelExporterOptions('export'));
112
+ // Or export the grid (respects filtering/sorting)
113
+ this.excelExporter.export(this.grid, new IgxExcelExporterOptions('export'));
114
+ }
115
+ }
116
+ ```
117
+
118
+ ### CSV Export
119
+
120
+ > **Docs:** [CSV Export](https://www.infragistics.com/products/ignite-ui-angular/angular/components/exporter-csv)
121
+
122
+ ```typescript
123
+ import { IgxCsvExporterService, IgxCsvExporterOptions, CsvFileTypes } from 'igniteui-angular/grids/core';
124
+
125
+ export class MyComponent {
126
+ private csvExporter = inject(IgxCsvExporterService);
127
+
128
+ exportToCsv() {
129
+ this.csvExporter.export(this.grid, new IgxCsvExporterOptions('export', CsvFileTypes.CSV));
130
+ }
131
+ }
132
+ ```
133
+
134
+ ## Virtualization & Performance
135
+
136
+ Grids use virtualization by default for both rows and columns — no setup needed. For remote data/paging:
137
+
138
+ ```html
139
+ <igx-grid [data]="data()" [totalItemCount]="totalCount" (dataPreLoad)="onDataPreLoad($event)">
140
+ </igx-grid>
141
+ ```
142
+
143
+ For full remote virtualization patterns — see [`paging-remote.md`](./paging-remote.md).
144
+
145
+ ## Row Drag
146
+
147
+ > **Docs:** [Row Drag](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/row-drag)
148
+
149
+ ```html
150
+ <igx-grid [rowDraggable]="true" (rowDragStart)="onDragStart($event)" (rowDragEnd)="onDragEnd($event)">
151
+ <ng-template igxRowDragGhost let-dragData>
152
+ <span>Moving {{ dragData.dragData.name }}</span>
153
+ </ng-template>
154
+ </igx-grid>
155
+ ```
156
+
157
+ ## Action Strip
158
+
159
+ > **Docs:** [Action Strip](https://www.infragistics.com/products/ignite-ui-angular/angular/components/action-strip)
160
+
161
+ Overlay actions on a row:
162
+
163
+ ```html
164
+ <igx-grid [data]="data()">
165
+ <igx-action-strip>
166
+ <igx-grid-editing-actions [addRow]="true"></igx-grid-editing-actions>
167
+ <igx-grid-pinning-actions></igx-grid-pinning-actions>
168
+ </igx-action-strip>
169
+ <igx-column field="name"></igx-column>
170
+ </igx-grid>
171
+ ```
172
+
173
+ ## Master-Detail (Grid only)
174
+
175
+ > **Docs:** [Master-Detail](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/master-detail)
176
+
177
+ Expand rows to show arbitrary detail content:
178
+
179
+ ```html
180
+ <igx-grid [data]="orders()" [primaryKey]="'orderId'">
181
+ <igx-column field="orderId"></igx-column>
182
+ <igx-column field="customer"></igx-column>
183
+
184
+ <ng-template igxGridDetail let-dataItem>
185
+ <div class="detail-container">
186
+ <h4>Order Items for {{ dataItem.customer }}</h4>
187
+ <igx-grid [data]="dataItem.items" [autoGenerate]="true" height="200px">
188
+ </igx-grid>
189
+ </div>
190
+ </ng-template>
191
+ </igx-grid>
192
+ ```
193
+
194
+ ## Clipboard
195
+
196
+ Grids support copy to clipboard by default. Configure via:
197
+
198
+ ```html
199
+ <igx-grid [clipboardOptions]="{ enabled: true, copyHeaders: true, copyFormatters: true, separator: '\t' }">
200
+ </igx-grid>
201
+ ```
202
+
203
+ ## Key Rules
204
+
205
+ 1. **Cancelable events** — use `event.cancel = true` in `(rowEdit)`, `(cellEdit)`, `(sorting)`, `(filtering)` to prevent the action
206
+ 2. **Use signals** for data binding — `[data]="myData()"` with `signal<T[]>([])`
207
+ 3. **Virtualization is automatic** — don't wrap grids in virtual scroll containers
208
+ 4. **GroupBy is Flat Grid only** — Tree Grid uses hierarchy, Hierarchical Grid uses row islands, Pivot Grid uses dimensions
209
+
210
+ ## See Also
211
+
212
+ - [`structure.md`](./structure.md) — Column config, sorting UI, filtering UI, selection
213
+ - [`types.md`](./types.md) — Tree Grid, Hierarchical Grid, Grid Lite, Pivot Grid specifics
214
+ - [`data-operations.md`](./data-operations.md) — Programmatic sorting, filtering, grouping
215
+ - [`paging-remote.md`](./paging-remote.md) — Paging, remote data operations, virtualization
216
+ - [`editing.md`](./editing.md) — Cell editing, row editing, batch editing, validation, summaries
217
+ - [`state.md`](./state.md) — State persistence
218
+ - [`../../igniteui-angular-theming/SKILL.md`](../../igniteui-angular-theming/SKILL.md) — Grid styling and theming