Events
Complete reference for all grid events with payload types and usage examples.
Events
ZenGrid provides a comprehensive event system for responding to user interactions and grid state changes.
Event Registration
// Register an event listenerconst unsubscribe = grid.on('cell:click', (event) => { console.log('Cell clicked:', event.cell, event.value);});
// Unregister when doneunsubscribe();
// Or use off()grid.off('cell:click', handler);All event listeners return an unsubscribe function for easy cleanup.
Cell Events
cell:click
Fired when a cell is clicked.
grid.on('cell:click', (event) => { console.log('Cell:', event.cell); console.log('Value:', event.value); console.log('Native event:', event.nativeEvent);});Payload:
cell: CellRef- Cell coordinates{ row, col }value: any- Cell valuenativeEvent: MouseEvent- Browser mouse event
cell:doubleClick
Fired when a cell is double-clicked.
grid.on('cell:doubleClick', (event) => { console.log('Cell double-clicked:', event.cell);});Payload:
cell: CellRef- Cell coordinatesvalue: any- Cell valuenativeEvent: MouseEvent- Browser mouse event
cell:contextMenu
Fired when a cell is right-clicked.
grid.on('cell:contextMenu', (event) => { event.nativeEvent.preventDefault(); // Show custom context menu});Payload:
cell: CellRef- Cell coordinatesvalue: any- Cell valuenativeEvent: MouseEvent- Browser mouse event
cell:change
Fired when a cell value changes.
grid.on('cell:change', (event) => { console.log('Cell changed:', event.cell); console.log('Old value:', event.oldValue); console.log('New value:', event.newValue);});Payload:
cell: CellRef- Cell coordinatesoldValue: any- Previous valuenewValue: any- New value
cell:beforeChange
Fired before a cell value changes. Can be cancelled.
grid.on('cell:beforeChange', (event) => { if (event.newValue < 0) { event.cancel = true; // Cancel the change }});Payload:
cell: CellRef- Cell coordinatesoldValue: any- Current valuenewValue: any- Proposed new valuecancel: boolean- Set totrueto cancel the change
cell:afterChange
Fired after a cell value changes.
grid.on('cell:afterChange', (event) => { console.log('Cell updated:', event.cell);});Payload:
cell: CellRef- Cell coordinatesoldValue: any- Previous valuenewValue: any- New value
Selection Events
selection:change
Fired when the selection changes.
grid.on('selection:change', (event) => { console.log('Current selection:', event.ranges); console.log('Previous selection:', event.previousRanges);});Payload:
ranges: CellRange[]- Array of selected rangespreviousRanges: CellRange[]- Previous selection
selection:start
Fired when a selection starts.
grid.on('selection:start', (event) => { console.log('Selection started at:', event.startCell);});Payload:
startCell: CellRef- Starting cell
selection:end
Fired when a selection ends.
grid.on('selection:end', (event) => { console.log('Final selection:', event.ranges);});Payload:
ranges: CellRange[]- Final selection ranges
Editing Events
edit:start
Fired when cell editing starts.
grid.on('edit:start', (event) => { console.log('Editing cell:', event.cell); console.log('Current value:', event.value);});Payload:
cell: CellRef- Cell being editedvalue: any- Current cell value
edit:end
Fired when cell editing ends.
grid.on('edit:end', (event) => { console.log('Editing ended:', event.cell); console.log('Cancelled:', event.cancelled);});Payload:
cell: CellRef- Cell that was editedvalue: any- Final valuecancelled: boolean- Whether editing was cancelled
edit:commit
Fired when an edit is committed.
grid.on('edit:commit', (event) => { console.log('Value committed:', event.newValue); // Send to server saveToServer(event.cell, event.newValue);});Payload:
cell: CellRef- Cell coordinatesoldValue: any- Previous valuenewValue: any- Committed value
edit:cancel
Fired when an edit is cancelled.
grid.on('edit:cancel', (event) => { console.log('Edit cancelled for:', event.cell);});Payload:
cell: CellRef- Cell coordinatesvalue: any- Unchanged value
Scroll Events
scroll
Fired when the grid is scrolled.
grid.on('scroll', (event) => { console.log('Scroll position:', event.scrollTop, event.scrollLeft); console.log('Visible range:', event.visibleRange);});Payload:
scrollTop: number- Vertical scroll positionscrollLeft: number- Horizontal scroll positionvisibleRange: VisibleRange- Currently visible cell range
scroll:start
Fired when scrolling starts.
grid.on('scroll:start', () => { console.log('Scrolling started');});Payload: None
scroll:end
Fired when scrolling ends.
grid.on('scroll:end', () => { console.log('Scrolling ended');});Payload: None
Sort Events
sort:change
Fired when the sort state changes.
grid.on('sort:change', (event) => { console.log('Current sort:', event.sortState); console.log('Previous sort:', event.previousSortState);});Payload:
sortState: SortState[]- Current sort statepreviousSortState: SortState[]- Previous sort state
sort:beforeSort
Fired before sorting is applied. Can be cancelled.
grid.on('sort:beforeSort', (event) => { if (event.sortState.length > 3) { event.cancel = true; // Limit to 3 sort columns }});Payload:
sortState: SortState[]- Proposed sort statecancel: boolean- Set totrueto cancel sorting
sort:afterSort
Fired after sorting is applied.
grid.on('sort:afterSort', (event) => { console.log('Sorting complete'); console.log('Rows affected:', event.rowsAffected);});Payload:
sortState: SortState[]- Applied sort staterowsAffected: number- Number of rows sorted
Filter Events
filter:change
Fired when the filter state changes.
grid.on('filter:change', (event) => { console.log('Current filters:', event.filterState); console.log('Previous filters:', event.previousFilterState);});Payload:
filterState: FilterModel[]- Current filter statepreviousFilterState: FilterModel[]- Previous filter state
filter:beforeFilter
Fired before filtering is applied. Can be cancelled.
grid.on('filter:beforeFilter', (event) => { // Validate filter state if (!isValidFilter(event.filterState)) { event.cancel = true; }});Payload:
filterState: FilterModel[]- Proposed filter statecancel: boolean- Set totrueto cancel filtering
filter:afterFilter
Fired after filtering is applied.
grid.on('filter:afterFilter', (event) => { console.log('Rows visible:', event.rowsVisible); console.log('Rows hidden:', event.rowsHidden);});Payload:
filterState: FilterModel[]- Applied filter staterowsVisible: number- Number of visible rowsrowsHidden: number- Number of hidden rows
filter:export
Fired when filter state is exported.
grid.on('filter:export', (event) => { console.log('SQL:', event.sql); console.log('REST:', event.rest); console.log('GraphQL:', event.graphql);});Payload:
state: FilterModel[]- Current filter staterest: object- REST API formatgraphql: object- GraphQL formatsql: string- SQL WHERE clausepreviousState: FilterModel[]- Previous filter state
Focus Events
focus:change
Fired when focus moves to a different cell.
grid.on('focus:change', (event) => { console.log('Focus moved to:', event.cell); console.log('Previous focus:', event.previousCell);});Payload:
cell: CellRef- Newly focused cellpreviousCell: CellRef | null- Previously focused cell
focus:in
Fired when a cell receives focus.
grid.on('focus:in', (event) => { console.log('Cell focused:', event.cell);});Payload:
cell: CellRef- Focused cell
focus:out
Fired when a cell loses focus.
grid.on('focus:out', (event) => { console.log('Cell blurred:', event.cell);});Payload:
cell: CellRef- Blurred cell
Keyboard Events
key:down
Fired when a key is pressed while the grid has focus.
grid.on('key:down', (event) => { if (event.key === 'Delete') { event.preventDefault(); // Custom delete logic }});Payload:
cell: CellRef- Focused cellkey: string- Key pressednativeEvent: KeyboardEvent- Browser keyboard eventpreventDefault: () => void- Prevent default behavior
key:up
Fired when a key is released.
grid.on('key:up', (event) => { console.log('Key released:', event.key);});Payload:
cell: CellRef- Focused cellkey: string- Key releasednativeEvent: KeyboardEvent- Browser keyboard event
key:press
Fired when a key press produces a character.
grid.on('key:press', (event) => { console.log('Character:', event.key);});Payload:
cell: CellRef- Focused cellkey: string- Character producednativeEvent: KeyboardEvent- Browser keyboard event
Clipboard Events
copy
Fired when content is copied.
grid.on('copy', (event) => { console.log('Copied ranges:', event.ranges); console.log('Data:', event.data);});Payload:
ranges: CellRange[]- Copied rangesdata: string- Copied data (TSV format)
cut
Fired when content is cut.
grid.on('cut', (event) => { console.log('Cut ranges:', event.ranges);});Payload:
ranges: CellRange[]- Cut rangesdata: string- Cut data (TSV format)
paste
Fired when content is pasted.
grid.on('paste', (event) => { console.log('Paste target:', event.cell); console.log('Pasted data:', event.data);});Payload:
cell: CellRef- Paste target celldata: string[][]- Pasted data
Lifecycle Events
render:start
Fired when rendering starts.
grid.on('render:start', () => { console.log('Rendering started');});Payload: None
render:end
Fired when rendering completes.
grid.on('render:end', (event) => { console.log('Render duration:', event.duration, 'ms');});Payload:
timestamp: number- Completion timestampduration: number- Render duration in milliseconds
data:load
Fired when data is loaded.
grid.on('data:load', (event) => { console.log('Loaded:', event.rowCount, 'rows,', event.colCount, 'columns');});Payload:
rowCount: number- Number of rows loadedcolCount: number- Number of columns loaded
data:change
Fired when the underlying data changes.
grid.on('data:change', () => { console.log('Data has changed');});Payload: None
destroy
Fired when the grid is destroyed.
grid.on('destroy', () => { console.log('Grid destroyed');});Payload: None
Loading Events
loading:start
Fired when a loading operation starts.
grid.on('loading:start', () => { console.log('Loading started');});Payload: None
loading:end
Fired when a loading operation completes.
grid.on('loading:end', () => { console.log('Loading completed');});Payload: None
loading:progress
Fired to report loading progress.
grid.on('loading:progress', (event) => { console.log('Progress:', event.progress, '%');});Payload:
progress: number- Progress percentage (0-100)
Column Events
column:resize
Fired when a column is resized.
grid.on('column:resize', (event) => { console.log('Column', event.column, 'resized'); console.log('Old width:', event.oldWidth); console.log('New width:', event.newWidth);});Payload:
column: number- Column indexoldWidth: number- Previous widthnewWidth: number- New width
column:move
Fired when a column is moved.
grid.on('column:move', (event) => { console.log('Column moved from', event.oldIndex, 'to', event.newIndex);});Payload:
column: number- Column indexoldIndex: number- Previous positionnewIndex: number- New position
column:hide
Fired when a column is hidden.
grid.on('column:hide', (event) => { console.log('Column hidden:', event.column);});Payload:
column: number- Column index
column:show
Fired when a column is shown.
grid.on('column:show', (event) => { console.log('Column shown:', event.column);});Payload:
column: number- Column index
column:dragStart
Fired when column drag starts.
grid.on('column:dragStart', (event) => { console.log('Dragging column:', event.column);});Payload:
column: number- Column being dragged
column:drag
Fired during column drag.
grid.on('column:drag', (event) => { console.log('Drag position:', event.x, event.y);});Payload:
column: number- Column being draggedx: number- Current X positiony: number- Current Y position
column:dragEnd
Fired when column drag ends successfully.
grid.on('column:dragEnd', (event) => { console.log('Column dropped at:', event.newIndex);});Payload:
column: number- Column that was draggedoldIndex: number- Starting positionnewIndex: number- Final position
column:dragCancel
Fired when column drag is cancelled.
grid.on('column:dragCancel', (event) => { console.log('Drag cancelled for column:', event.column);});Payload:
column: number- Column that was being dragged
Header Events
header:click
Fired when a header is clicked.
grid.on('header:click', (event) => { console.log('Header clicked:', event.columnIndex); console.log('Column definition:', event.column);});Payload:
columnIndex: number- Column indexcolumn: ColumnDef- Column definitionnativeEvent: MouseEvent- Browser mouse event
header:doubleClick
Fired when a header is double-clicked.
grid.on('header:doubleClick', (event) => { // Auto-fit column on double-click grid.autoFitColumn(event.columnIndex);});Payload:
columnIndex: number- Column indexcolumn: ColumnDef- Column definitionnativeEvent: MouseEvent- Browser mouse event
header:contextMenu
Fired when a header is right-clicked.
grid.on('header:contextMenu', (event) => { event.nativeEvent.preventDefault(); // Show column menu});Payload:
columnIndex: number- Column indexcolumn: ColumnDef- Column definitionnativeEvent: MouseEvent- Browser mouse event
header:hover
Fired when a header is hovered.
grid.on('header:hover', (event) => { console.log('Hovering column:', event.columnIndex);});Payload:
columnIndex: number- Column indexcolumn: ColumnDef- Column definition
header:sort:click
Fired when a sort icon in the header is clicked.
grid.on('header:sort:click', (event) => { console.log('Sort clicked for column:', event.columnIndex);});Payload:
columnIndex: number- Column index
header:filter:click
Fired when a filter icon in the header is clicked.
grid.on('header:filter:click', (event) => { console.log('Filter clicked for column:', event.columnIndex);});Payload:
columnIndex: number- Column index
header:checkbox:change
Fired when a header checkbox changes (for row selection).
grid.on('header:checkbox:change', (event) => { console.log('Select all:', event.checked);});Payload:
checked: boolean- Checkbox state
Row Events
row:insert
Fired when a row is inserted.
grid.on('row:insert', (event) => { console.log('Row inserted at:', event.rowIndex);});Payload:
rowIndex: number- Inserted row index
row:delete
Fired when a row is deleted.
grid.on('row:delete', (event) => { console.log('Row deleted:', event.rowIndex);});Payload:
rowIndex: number- Deleted row index
row:move
Fired when a row is moved.
grid.on('row:move', (event) => { console.log('Row moved from', event.oldIndex, 'to', event.newIndex);});Payload:
oldIndex: number- Previous positionnewIndex: number- New position
Undo-Redo Events
undo-redo:change
Fired when the undo/redo state changes.
grid.on('undo-redo:change', (event) => { console.log('Can undo:', event.canUndo); console.log('Can redo:', event.canRedo); console.log('Undo stack size:', event.undoCount); console.log('Redo stack size:', event.redoCount);});Payload:
canUndo: boolean- Whether undo is availablecanRedo: boolean- Whether redo is availableundoCount: number- Number of undo operations availableredoCount: number- Number of redo operations available
Error Events
error
Fired when an error occurs.
grid.on('error', (event) => { console.error('Grid error:', event.message); console.error('Error object:', event.error); console.error('Context:', event.context);});Payload:
message: string- Error messageerror: Error- Error objectcontext?: object- Additional context
warning
Fired when a warning occurs.
grid.on('warning', (event) => { console.warn('Grid warning:', event.message);});Payload:
message: string- Warning messagecontext?: object- Additional context
All events support multiple listeners. Listeners are called in the order they were registered.