0
# Events and Handlers
1
2
RevoGrid provides a comprehensive event system covering all grid interactions including data changes, user interactions, lifecycle events, and plugin events. All events follow modern naming conventions and provide detailed event information.
3
4
## Capabilities
5
6
### Data Events
7
8
Events related to data changes and editing operations.
9
10
```typescript { .api }
11
/**
12
* Before cell edit event - fired before cell value changes
13
*/
14
addEventListener(type: 'beforeedit', listener: (e: CustomEvent<BeforeSaveDataDetails>) => void): void;
15
16
/**
17
* Before range edit event - fired before range data changes
18
*/
19
addEventListener(type: 'beforerangeedit', listener: (e: CustomEvent<BeforeRangeSaveDataDetails>) => void): void;
20
21
/**
22
* After edit event - fired after data change is complete
23
*/
24
addEventListener(type: 'afteredit', listener: (e: CustomEvent<AfterEditEvent>) => void): void;
25
26
/**
27
* Before autofill operation
28
*/
29
addEventListener(type: 'beforeautofill', listener: (e: CustomEvent<ChangedRange>) => void): void;
30
31
/**
32
* Before range change operation
33
*/
34
addEventListener(type: 'beforerange', listener: (e: CustomEvent<ChangedRange>) => void): void;
35
36
/**
37
* Before cell edit event detail
38
*/
39
interface BeforeSaveDataDetails {
40
/** New value being set */
41
val: any;
42
/** Previous value */
43
oldVal: any;
44
/** Row data object */
45
row: DataType;
46
/** Column definition */
47
col: ColumnRegular;
48
/** All grid data */
49
models: DataType[];
50
}
51
52
/**
53
* Before range edit event detail
54
*/
55
interface BeforeRangeSaveDataDetails {
56
/** Range being modified */
57
range: RangeArea;
58
/** Data being set */
59
data: any[][];
60
/** Models being affected */
61
models: DataType[];
62
}
63
64
/**
65
* After edit event detail
66
*/
67
interface AfterEditEvent {
68
/** New value that was set */
69
val: any;
70
/** Previous value */
71
oldVal: any;
72
/** Updated row data */
73
row: DataType;
74
/** Column definition */
75
col: ColumnRegular;
76
/** Updated grid data */
77
models: DataType[];
78
}
79
80
/**
81
* Changed range information
82
*/
83
interface ChangedRange {
84
/** Range that changed */
85
range: RangeArea;
86
/** Change type */
87
type: string;
88
/** Source dimension */
89
source: DimensionRows;
90
}
91
```
92
93
**Usage Example:**
94
95
```typescript
96
// Handle cell editing events
97
grid.addEventListener('beforeedit', (e) => {
98
const { val, oldVal, col, row } = e.detail;
99
100
// Validate new value
101
if (col.prop === 'age' && (val < 0 || val > 120)) {
102
e.preventDefault(); // Cancel the edit
103
alert('Age must be between 0 and 120');
104
return;
105
}
106
107
console.log(`Changing ${col.prop} from ${oldVal} to ${val}`);
108
});
109
110
grid.addEventListener('afteredit', (e) => {
111
const { val, col, row } = e.detail;
112
console.log(`Successfully updated ${col.prop} to ${val} in row:`, row);
113
114
// Trigger additional actions
115
if (col.prop === 'status') {
116
// Update related fields or trigger API calls
117
}
118
});
119
120
// Handle range operations
121
grid.addEventListener('beforerangeedit', (e) => {
122
const { range, data } = e.detail;
123
console.log(`Updating range from (${range.x},${range.y}) to (${range.x1},${range.y1})`);
124
console.log('New data:', data);
125
});
126
```
127
128
### Source Events
129
130
Events related to data source management and changes.
131
132
```typescript { .api }
133
/**
134
* Before main source is set
135
*/
136
addEventListener(type: 'beforesourceset', listener: (e: CustomEvent<SourceSetEvent>) => void): void;
137
138
/**
139
* Before any source is set (including pinned)
140
*/
141
addEventListener(type: 'beforeanysource', listener: (e: CustomEvent<SourceSetEvent>) => void): void;
142
143
/**
144
* After main source is set
145
*/
146
addEventListener(type: 'aftersourceset', listener: (e: CustomEvent<SourceSetEvent>) => void): void;
147
148
/**
149
* After any source is set (including pinned)
150
*/
151
addEventListener(type: 'afteranysource', listener: (e: CustomEvent<SourceSetEvent>) => void): void;
152
153
/**
154
* Source set event detail
155
*/
156
interface SourceSetEvent {
157
/** Dimension type being set */
158
type: DimensionRows;
159
/** Data source being set */
160
source: DataType[];
161
}
162
```
163
164
**Usage Example:**
165
166
```typescript
167
// Monitor data source changes
168
grid.addEventListener('beforesourceset', (e) => {
169
const { type, source } = e.detail;
170
console.log(`Setting ${type} data with ${source.length} items`);
171
172
// Perform data validation or transformation
173
if (source.length > 10000) {
174
console.warn('Large dataset detected, performance may be affected');
175
}
176
});
177
178
grid.addEventListener('aftersourceset', (e) => {
179
const { type, source } = e.detail;
180
console.log(`Successfully set ${type} data`);
181
182
// Update UI or trigger related operations
183
updateDataSummary(source);
184
});
185
```
186
187
### Column Events
188
189
Events related to column operations and changes.
190
191
```typescript { .api }
192
/**
193
* Before columns are set
194
*/
195
addEventListener(type: 'beforecolumnsset', listener: (e: CustomEvent<ColumnCollection>) => void): void;
196
197
/**
198
* Before columns are applied to grid
199
*/
200
addEventListener(type: 'beforecolumnapplied', listener: (e: CustomEvent<ColumnCollection>) => void): void;
201
202
/**
203
* After columns are set
204
*/
205
addEventListener(type: 'aftercolumnsset', listener: (e: CustomEvent<AfterColumnsSetEvent>) => void): void;
206
207
/**
208
* After column resize operation
209
*/
210
addEventListener(type: 'aftercolumnresize', listener: (e: CustomEvent<ColumnResizeEvent>) => void): void;
211
212
/**
213
* After columns set event detail
214
*/
215
interface AfterColumnsSetEvent {
216
/** Updated column definitions */
217
columns: ColumnRegular[];
218
/** Column order mapping */
219
order: Record<string, number>;
220
}
221
222
/**
223
* Column resize event detail
224
*/
225
interface ColumnResizeEvent {
226
/** Map of column index to updated column */
227
[index: number]: ColumnRegular;
228
}
229
230
/**
231
* Column collection type
232
*/
233
interface ColumnCollection {
234
/** Column definitions */
235
columns: ColumnRegular[];
236
/** Column grouping information */
237
groups?: ColumnGrouping[];
238
/** Column order */
239
order: Record<string, number>;
240
}
241
```
242
243
**Usage Example:**
244
245
```typescript
246
// Handle column configuration changes
247
grid.addEventListener('beforecolumnsset', (e) => {
248
const { columns } = e.detail;
249
console.log('Setting columns:', columns.map(c => c.name));
250
251
// Validate column configuration
252
const duplicateProps = findDuplicateProps(columns);
253
if (duplicateProps.length > 0) {
254
console.error('Duplicate column properties found:', duplicateProps);
255
e.preventDefault();
256
}
257
});
258
259
grid.addEventListener('aftercolumnsset', (e) => {
260
const { columns, order } = e.detail;
261
console.log('Columns set successfully:', columns.length);
262
263
// Save column configuration
264
saveColumnConfiguration(columns, order);
265
});
266
267
grid.addEventListener('aftercolumnresize', (e) => {
268
const resizedColumns = e.detail;
269
console.log('Columns resized:', Object.keys(resizedColumns));
270
271
// Persist column sizes
272
Object.entries(resizedColumns).forEach(([index, column]) => {
273
saveColumnSize(column.prop, column.size);
274
});
275
});
276
```
277
278
### Selection Events
279
280
Events related to cell focus and selection operations.
281
282
```typescript { .api }
283
/**
284
* Before cell focus changes
285
*/
286
addEventListener(type: 'beforecellfocus', listener: (e: CustomEvent<BeforeSaveDataDetails>) => void): void;
287
288
/**
289
* Before focus is lost
290
*/
291
addEventListener(type: 'beforefocuslost', listener: (e: CustomEvent<FocusedData | null>) => void): void;
292
293
/**
294
* After focus render is complete
295
*/
296
addEventListener(type: 'afterfocus', listener: (e: CustomEvent<FocusAfterRenderEvent>) => void): void;
297
298
/**
299
* Focused data information
300
*/
301
interface FocusedData {
302
/** Focused cell coordinate */
303
cell: Cell;
304
/** Cell value */
305
val: any;
306
/** Row dimension type */
307
rowType: DimensionRows;
308
/** Column dimension type */
309
colType: DimensionCols;
310
}
311
312
/**
313
* After focus render event detail
314
*/
315
interface FocusAfterRenderEvent {
316
/** New focus data */
317
focus: FocusedData;
318
/** Previous focus data */
319
prevFocus?: FocusedData;
320
}
321
```
322
323
**Usage Example:**
324
325
```typescript
326
// Handle focus and selection events
327
grid.addEventListener('beforecellfocus', (e) => {
328
const { row, col } = e.detail;
329
console.log(`Focusing cell ${col.prop} in row:`, row);
330
331
// Custom focus validation
332
if (row.locked) {
333
e.preventDefault();
334
showMessage('Cannot focus on locked row');
335
}
336
});
337
338
grid.addEventListener('afterfocus', (e) => {
339
const { focus, prevFocus } = e.detail;
340
console.log(`Focus moved from (${prevFocus?.cell.x},${prevFocus?.cell.y}) to (${focus.cell.x},${focus.cell.y})`);
341
342
// Update UI elements based on focus
343
updatePropertyPanel(focus.val, focus.rowType, focus.colType);
344
});
345
```
346
347
### Sorting Events
348
349
Events related to sorting operations.
350
351
```typescript { .api }
352
/**
353
* Before sorting operation
354
*/
355
addEventListener(type: 'beforesorting', listener: (e: CustomEvent<BeforeSortingEvent>) => void): void;
356
357
/**
358
* Before source sorting is applied
359
*/
360
addEventListener(type: 'beforesourcesortingapply', listener: (e: CustomEvent<BeforeSourceSortingEvent>) => void): void;
361
362
/**
363
* Before sorting is applied to column
364
*/
365
addEventListener(type: 'beforesortingapply', listener: (e: CustomEvent<BeforeSortingEvent>) => void): void;
366
367
/**
368
* Before sorting event detail
369
*/
370
interface BeforeSortingEvent {
371
/** Column being sorted */
372
column: ColumnRegular;
373
/** Sort order */
374
order: Order;
375
/** Whether this is additive to existing sort */
376
additive: boolean;
377
}
378
379
/**
380
* Before source sorting event detail
381
*/
382
interface BeforeSourceSortingEvent {
383
/** Dimension type being sorted */
384
type: DimensionRows;
385
/** Sorting configuration */
386
sorting: SortingConfig;
387
}
388
389
/**
390
* Sorting configuration
391
*/
392
interface SortingConfig {
393
/** Columns to sort by */
394
sortBy?: ColumnProp[];
395
/** Enable multi-column sorting */
396
multiColumn?: boolean;
397
}
398
```
399
400
**Usage Example:**
401
402
```typescript
403
// Handle sorting events
404
grid.addEventListener('beforesorting', (e) => {
405
const { column, order, additive } = e.detail;
406
console.log(`Sorting column ${column.prop} in ${order} order, additive: ${additive}`);
407
408
// Custom sorting validation
409
if (column.prop === 'id' && order === 'desc') {
410
console.warn('Descending sort on ID may affect performance');
411
}
412
});
413
414
grid.addEventListener('beforesortingapply', (e) => {
415
const { column, order } = e.detail;
416
console.log(`Applying sort to ${column.prop}`);
417
418
// Show loading indicator for large datasets
419
if (grid.source.length > 5000) {
420
showLoadingIndicator('Sorting large dataset...');
421
}
422
});
423
```
424
425
### Filter Events
426
427
Events related to filtering operations.
428
429
```typescript { .api }
430
/**
431
* Before filter is applied
432
*/
433
addEventListener(type: 'beforefilterapply', listener: (e: CustomEvent<BeforeFilterEvent>) => void): void;
434
435
/**
436
* Before filtered items are trimmed
437
*/
438
addEventListener(type: 'beforefiltertrimmed', listener: (e: CustomEvent<BeforeFilterTrimmedEvent>) => void): void;
439
440
/**
441
* Before items are trimmed/hidden
442
*/
443
addEventListener(type: 'beforetrimmed', listener: (e: CustomEvent<BeforeTrimmedEvent>) => void): void;
444
445
/**
446
* After trimmed operation is complete
447
*/
448
addEventListener(type: 'aftertrimmed', listener: (e: CustomEvent<void>) => void): void;
449
450
/**
451
* Before filter event detail
452
*/
453
interface BeforeFilterEvent {
454
/** Filter collection being applied */
455
collection: FilterCollection;
456
}
457
458
/**
459
* Before filter trimmed event detail
460
*/
461
interface BeforeFilterTrimmedEvent {
462
/** Filter collection */
463
collection: FilterCollection;
464
/** Items to be filtered out */
465
itemsToFilter: number[];
466
}
467
468
/**
469
* Before trimmed event detail
470
*/
471
interface BeforeTrimmedEvent {
472
/** Trimmed configuration */
473
trimmed: Record<number, boolean>;
474
/** Type of trimmed operation */
475
trimmedType: string;
476
/** Dimension type */
477
type: DimensionRows;
478
}
479
480
/**
481
* Filter collection type
482
*/
483
interface FilterCollection {
484
[columnProp: string]: FilterData;
485
}
486
487
/**
488
* Filter data for individual column
489
*/
490
interface FilterData {
491
/** Filter type */
492
type: string;
493
/** Filter criteria */
494
criteria: any;
495
/** Filter function */
496
filter?: (value: any, criteria: any) => boolean;
497
}
498
```
499
500
**Usage Example:**
501
502
```typescript
503
// Handle filtering events
504
grid.addEventListener('beforefilterapply', (e) => {
505
const { collection } = e.detail;
506
const activeFilters = Object.keys(collection);
507
console.log('Applying filters to columns:', activeFilters);
508
509
// Validate filter criteria
510
for (const [column, filterData] of Object.entries(collection)) {
511
if (!filterData.criteria) {
512
console.warn(`Empty filter criteria for column ${column}`);
513
}
514
}
515
});
516
517
grid.addEventListener('beforefiltertrimmed', (e) => {
518
const { collection, itemsToFilter } = e.detail;
519
console.log(`Filtering will hide ${itemsToFilter.length} rows`);
520
521
// Show filter summary
522
updateFilterSummary(collection, itemsToFilter.length);
523
});
524
525
grid.addEventListener('aftertrimmed', (e) => {
526
console.log('Filter operation completed');
527
528
// Update UI to reflect filtered state
529
updateRowCountDisplay();
530
hideLoadingIndicator();
531
});
532
```
533
534
### UI Events
535
536
Events related to user interface interactions.
537
538
```typescript { .api }
539
/**
540
* Header click event
541
*/
542
addEventListener(type: 'headerclick', listener: (e: CustomEvent<ColumnRegular>) => void): void;
543
544
/**
545
* Row drag start event
546
*/
547
addEventListener(type: 'rowdragstart', listener: (e: CustomEvent<RowDragStartDetails>) => void): void;
548
549
/**
550
* Row order changed event
551
*/
552
addEventListener(type: 'roworderchanged', listener: (e: CustomEvent<RowOrderChangeEvent>) => void): void;
553
554
/**
555
* Viewport scroll event
556
*/
557
addEventListener(type: 'viewportscroll', listener: (e: CustomEvent<ViewPortScrollEvent>) => void): void;
558
559
/**
560
* Row drag start details
561
*/
562
interface RowDragStartDetails {
563
/** Row being dragged */
564
row: DataType;
565
/** Row index */
566
index: number;
567
/** Dimension type */
568
type: DimensionRows;
569
}
570
571
/**
572
* Row order change event detail
573
*/
574
interface RowOrderChangeEvent {
575
/** Source row index */
576
from: number;
577
/** Target row index */
578
to: number;
579
}
580
581
/**
582
* Viewport scroll event detail
583
*/
584
interface ViewPortScrollEvent {
585
/** Scroll position */
586
coordinate: {
587
x: number;
588
y: number;
589
};
590
/** Dimension type */
591
dimension: DimensionRows | DimensionCols;
592
}
593
```
594
595
**Usage Example:**
596
597
```typescript
598
// Handle UI interaction events
599
grid.addEventListener('headerclick', (e) => {
600
const column = e.detail;
601
console.log(`Header clicked for column: ${column.name}`);
602
603
// Custom header click behavior
604
if (column.prop === 'actions') {
605
showColumnMenu(column);
606
}
607
});
608
609
grid.addEventListener('rowdragstart', (e) => {
610
const { row, index, type } = e.detail;
611
console.log(`Starting to drag row ${index} from ${type}`);
612
613
// Custom drag validation
614
if (row.locked) {
615
e.preventDefault();
616
showMessage('Cannot drag locked row');
617
}
618
});
619
620
grid.addEventListener('roworderchanged', (e) => {
621
const { from, to } = e.detail;
622
console.log(`Row moved from position ${from} to ${to}`);
623
624
// Save new order or trigger API update
625
saveRowOrder(from, to);
626
});
627
628
grid.addEventListener('viewportscroll', (e) => {
629
const { coordinate, dimension } = e.detail;
630
console.log(`Viewport scrolled in ${dimension} to:`, coordinate);
631
632
// Update scroll-based UI elements
633
updateScrollIndicator(coordinate, dimension);
634
});
635
```
636
637
### Lifecycle Events
638
639
Events related to grid lifecycle and initialization.
640
641
```typescript { .api }
642
/**
643
* Before grid render
644
*/
645
addEventListener(type: 'beforegridrender', listener: (e: CustomEvent<void>) => void): void;
646
647
/**
648
* After grid render is complete
649
*/
650
addEventListener(type: 'aftergridrender', listener: (e: CustomEvent<void>) => void): void;
651
652
/**
653
* After grid initialization is complete
654
*/
655
addEventListener(type: 'aftergridinit', listener: (e: CustomEvent<void>) => void): void;
656
657
/**
658
* Grid created event
659
*/
660
addEventListener(type: 'created', listener: (e: CustomEvent<void>) => void): void;
661
662
/**
663
* Content size changed
664
*/
665
addEventListener(type: 'contentsizechanged', listener: (e: CustomEvent<MultiDimensionType>) => void): void;
666
667
/**
668
* Multi-dimension type for size events
669
*/
670
interface MultiDimensionType {
671
[key: string]: number;
672
}
673
```
674
675
**Usage Example:**
676
677
```typescript
678
// Handle grid lifecycle events
679
grid.addEventListener('created', (e) => {
680
console.log('Grid component created');
681
682
// Initialize custom functionality
683
initializeCustomFeatures();
684
});
685
686
grid.addEventListener('aftergridinit', (e) => {
687
console.log('Grid initialization completed');
688
689
// Grid is ready for interaction
690
enableUserInteractions();
691
loadInitialData();
692
});
693
694
grid.addEventListener('contentsizechanged', (e) => {
695
const sizes = e.detail;
696
console.log('Content size changed:', sizes);
697
698
// Update layout or scroll indicators
699
updateLayoutBasedOnSize(sizes);
700
});
701
```
702
703
### Configuration Events
704
705
Events related to configuration changes.
706
707
```typescript { .api }
708
/**
709
* Filter configuration changed
710
*/
711
addEventListener(type: 'filterconfigchanged', listener: (e: CustomEvent<void>) => void): void;
712
713
/**
714
* Sorting configuration changed
715
*/
716
addEventListener(type: 'sortingconfigchanged', listener: (e: CustomEvent<SortingConfig>) => void): void;
717
718
/**
719
* Row headers configuration changed
720
*/
721
addEventListener(type: 'rowheaderschanged', listener: (e: CustomEvent<void>) => void): void;
722
723
/**
724
* Additional data changed
725
*/
726
addEventListener(type: 'additionaldatachanged', listener: (e: CustomEvent<any>) => void): void;
727
728
/**
729
* Theme changed
730
*/
731
addEventListener(type: 'afterthemechanged', listener: (e: CustomEvent<Theme>) => void): void;
732
733
/**
734
* Export events
735
*/
736
addEventListener(type: 'beforeexport', listener: (e: CustomEvent<DataInput>) => void): void;
737
738
/**
739
* Data input for export
740
*/
741
interface DataInput {
742
/** Data to export */
743
data: DataType[];
744
/** Export options */
745
options?: ExportOptions;
746
}
747
748
/**
749
* Export options
750
*/
751
interface ExportOptions {
752
/** Export format */
753
format: 'csv' | 'excel' | 'json';
754
/** Include headers */
755
includeHeaders?: boolean;
756
/** File name */
757
filename?: string;
758
}
759
```
760
761
**Usage Example:**
762
763
```typescript
764
// Handle configuration change events
765
grid.addEventListener('sortingconfigchanged', (e) => {
766
const config = e.detail;
767
console.log('Sorting configuration changed:', config);
768
769
// Save user preferences
770
saveUserPreferences({ sorting: config });
771
});
772
773
grid.addEventListener('afterthemechanged', (e) => {
774
const newTheme = e.detail;
775
console.log(`Theme changed to: ${newTheme}`);
776
777
// Update application theme
778
updateApplicationTheme(newTheme);
779
});
780
781
grid.addEventListener('beforeexport', (e) => {
782
const { data, options } = e.detail;
783
console.log(`Exporting ${data.length} rows in ${options?.format} format`);
784
785
// Add export metadata
786
if (options) {
787
options.filename = options.filename || `grid-export-${Date.now()}`;
788
}
789
});
790
```