Expand All

  Getting Started

  Reference

  Features

  Row Models

  Themes

  Components

  Examples

  Third Party

Misc

Github stars make projects look great. Please help, donate a star, it's free.
Read about ag-Grid's Partnership with webpack.
Get informed on releases and other ag-Grid news only - never spam.
Follow on Twitter

Cell Editors

Create your own cell editor by providing a cell editor component.

The interface for the cell editor component is as follows:

interface ICellEditorComp { // gets called once after the editor is created init?(params: ICellEditorParams): void; // Gets called once after GUI is attached to DOM. // Useful if you want to focus or highlight a component // (this is not possible when the element is not attached) afterGuiAttached?(): void; // Return the DOM element of your editor, this is what the grid puts into the DOM getGui(): HTMLElement; // Should return the final value to the grid, the result of the editing getValue(): any; // Gets called once by grid after editing is finished // if your editor needs to do any cleanup, do it here destroy?(): void; // Gets called once after initialised. // If you return true, the editor will appear in a popup isPopup?(): boolean; // Gets called once before editing starts, to give editor a chance to // cancel the editing before it even starts. isCancelBeforeStart?(): boolean; // Gets called once when editing is finished (eg if enter is pressed). // If you return true, then the result of the edit will be ignored. isCancelAfterEnd?(): boolean; // If doing full row edit, then gets called when tabbing into the cell. focusIn?(): boolean; // If doing full row edit, then gets called when tabbing out of the cell. focusOut?(): boolean; }

Below is a simple example of Cell Editor:

// function to act as a class function MyCellEditor () {} // gets called once before the renderer is used MyCellEditor.prototype.init = function(params) { // create the cell this.eInput = document.createElement('input'); this.eInput.value = params.value; }; // gets called once when grid ready to insert the element MyCellEditor.prototype.getGui = function() { return this.eInput; }; // focus and select can be done after the gui is attached MyCellEditor.prototype.afterGuiAttached = function() { this.eInput.focus(); this.eInput.select(); }; // returns the new value after editing MyCellEditor.prototype.getValue = function() { return this.eInput.value; }; // any cleanup we need to be done here MyCellEditor.prototype.destroy = function() { // but this example is simple, no cleanup, we could // even leave this method out as it's optional }; // if true, then this editor will appear in a popup MyCellEditor.prototype.isPopup = function() { and we could leave this method out also, false is the default return false; };

Cell Editor Params

The Cell Editor component takes parameters in its init() method and contain the following:

Value Description
value The initial data value to be edited.
keyPress If editing was started by a function key press, contains the key code.
charPress If editing was started by a printable character, contains the string of the printable character.
column The column the cell belongs to.
node The row node the row is rendering.
api Grid API
columnApi Column API
context Grid context
$scope If compiling to Angular, is the row's child scope, otherwise null.
onKeyDown Callback to tell grid a key was pressed - useful to pass control key events (tab, arrows etc) back to grid - however you do not need to call this as the grid is already listening for the events as they propagate. This is only required if you are preventing event propagation.
stopEditing Callback to tell grid to stop editing the current cell.
eGridCell A reference to the DOM element representing the grid cell that your component will live inside. Useful if you want to add event listeners or classes at this level. This is the DOM element that gets browser focus when selecting cells.
cellStartedEdit If doing full row edit, this is true if the cell is the one that started the edit (eg it is the cell the use double clicked on, or pressed a key on etc).
useFormatter This is useful when using reference data and you want to show display text rather than the underlying code value. If true, the formatter provided on the ColDef will format the value prior to editing.

Complementing Cell Editor Params

Again like cell renderer's, cell editors can also be provided with additional parameters. Do this using cellEditorParams like in the following example which will pass 'Ireland' as the 'country' parameter:

// define cell renderer to be reused var myCellEditor = ..... // use with a color colDef.cellEditor = ... // provide cellEditor as before colDef.cellEditorParams = { country: 'Ireland' }

Keyboard Navigation While Editing

If you provide a cell editor, you may wish to disable some of the grids keyboard navigation. For example, if you are providing a simple text editor, you may wish the grid to do nothing when you press the right and left arrows (the default is the grid will move to the next / previous cell) as you may want the right and left arrows to move the cursor inside your editor. In other cell editors, you may wish the grid to behave as normal.

Because different cell editors will have different requirements on what the grid does, it is up to the cell editor to decide which event it wants the grid to handle and which it does not.

You have two options to stop the grid from doing it's default action on certain key events:

  1. Stop propagation of the event to the grid in the cell editor.
  2. Tell the grid to do nothing via the colDef.suppressKeyEvent() callback.

Option 1 - Stop Propagation

If you don't want the grid to act on an event, call event.stopPropagation(). The advantage of this method is that your cell editor takes care of everything, good for creating reusable cell editors.

The follow code snippet is one you could include for a simple text editor, which would stop the grid from doing navigation.

var KEY_LEFT = 37; var KEY_UP = 38; var KEY_RIGHT = 39; var KEY_DOWN = 40; var KEY_PAGE_UP = 33; var KEY_PAGE_DOWN = 34; var KEY_PAGE_HOME = 36; var KEY_PAGE_END = 35; eInputDomElement.addEventListener('keydown', function(event) { var keyCode = event.keyCode; var isNavigationKey = keyCode===KEY_LEFT || keyCode===KEY_RIGHT || keyCode===KEY_UP || keyCode===KEY_DOWN || keyCode===KEY_PAGE_DOWN || keyCode===KEY_PAGE_UP || keyCode===KEY_PAGE_HOME || keyCode===KEY_PAGE_END; if (isNavigationKey) { // this stops the grid from receiving the event and executing keyboard navigation event.stopPropagation(); } }

Option 2 - Suppress Keyboard Event

If you implement colDef.suppressKeyboardEvent(), you can tell the grid which events you want process and which not. The advantage of this method of the previous method is it takes the responsibility out of the cell editor and into the column definition. So if you are using a reusable, or third party, cell editor, and the editor doesn't have this logic in it, you can add the logic via configuration.

var KEY_UP = 38; var KEY_DOWN = 40; colDef.suppressKeyboardEvent = function(params) { console.log('cell is editing: ' + params.editing); console.log('keyboard event:', params.event); // return true (to suppress) if editing and user hit up/down keys var keyCode = params.event.keyCode; var gridShouldDoNothing = params.editing && (keyCode===KEY_UP || keyCode===KEY_DOWN); return gridShouldDoNothing; }

The params for suppressKeyboardEvent() are as follows:

interface SuppressKeyboardEventParams { // the keyboard event the grid received event: KeyboardEvent; // whether the cell is editing or not editing: boolean; // these are same as normal node: RowNode; column: Column; colDef: ColDef; context: any; api: GridApi; columnApi: ColumnApi; }

Cell Editing Example

The example below illustrates:

  • 'Gender' column uses a Component cell editor that allows choices via a 'richSelect' (ag-Grid-Enterprise only), with values supplied by complementing the editor parameters.
  • 'Age' column uses a Component cell editor that allows simple integer input only.
  • 'Mood' column uses a custom Component cell editor and renderer that allows choice of mood based on image selection.
  • 'Address' column uses a Component cell editor that allows input of multiline text via a 'largeText'. Tab & Esc (amongst others) will exit editing in this field, Shift+Enter will allow newlines.
  • 'Country' columns shows using 'richSelect' for a complex object - the cell renderer takes care of only rendering the country name.

Angular Cell Editing

This section explains how to utilise ag-Grid Cell Editors using Angular 2+. You should read about how Cell Editing works in ag-Grid first before trying to understand this section.

It is possible to provide a Angular Cell Editor for ag-Grid to use. All of the information above is relevant to Angular Cell Editors. This section explains how to apply this logic to your Angular component.

For an example of Angular cellEditing, see the ag-grid-angular-example on Github.

Specifying a Angular Cell Editor

If you are using the ag-grid-angular component to create the ag-Grid instance, then you will have the option of additionally specifying the cell editors as Angular components.

// create your Cell Editor as a Angular component @Component({ selector: 'editor-cell', template: ` <div #container class="mood" tabindex="0" (keydown)="onKeyDown($event)"> <img src="../images/smiley.png" (click)="setHappy(true)" [ngClass]="{'selected' : happy, 'default' : !happy}"> <img src="../images/smiley-sad.png" (click)="setHappy(false)" [ngClass]="{'selected' : !happy, 'default' : happy}"> </div> `, styles: [` .mood { border-radius: 15px; border: 1px solid grey; background: #e6e6e6; padding: 15px; text-align:center; display:inline-block; outline:none } .default { padding-left:10px; padding-right:10px; border: 1px solid transparent; padding: 4px; } .selected { padding-left:10px; padding-right:10px; border: 1px solid lightgreen; padding: 4px; } `] }) class MoodEditorComponent implements AgEditorComponent, AfterViewInit { private params:any; @ViewChild('container', {read: ViewContainerRef}) container; private happy:boolean = false; // dont use afterGuiAttached for post gui events - hook into ngAfterViewInit instead for this ngAfterViewInit() { this.container.element.nativeElement.focus(); } agInit(params:any):void { this.params = params; this.setHappy(params.value === "Happy"); } getValue():any { return this.happy ? "Happy" : "Sad"; } isPopup():boolean { return true; } setHappy(happy:boolean):void { this.happy = happy; } toggleMood():void { this.setHappy(!this.happy); } onKeyDown(event):void { let key = event.which || event.keyCode; if (key == 37 || // left key == 39) { // right this.toggleMood(); event.stopPropagation(); } } } // then reference the Component in your colDef like this colDef = { headerName: "Mood", field: "mood", // instead of cellEditor we use cellEditorFramework cellEditorFramework: MoodEditorComponent, // specify all the other fields as normal editable: true, width: 150 } }

Your Angular components need to implement AgEditorComponent.

By using colDef.cellEditorFramework (instead of colDef.cellEditor) the grid will know it's an Angular component, based on the fact that you are using the Angular version of ag-Grid.

Angular Parameters

Your Angular components need to implement AgEditorComponent. The ag Framework expects to find the agInit method on the created component, and uses it to supply the cell params.

Angular Methods / Lifecycle

All of the methods in the ICellEditor interface described above are applicable to the Angular Component with the following exceptions:

  • init() is not used. Instead implement the agInit method (on the AgRendererComponent interface).
  • destroy() is not used. Instead implement the AngularOnDestroy interface (ngOnDestroy) for any cleanup you need to do.
  • getGui() is not used. Instead do normal Angular magic in your Component via the Angular template.
  • afterGuiAttached() is not used. Instead implement AfterViewInit (ngAfterViewInit) for any post Gui setup (ie to focus on an element).

All of the other methods (isPopup(), getValue(), isCancelBeforeStart(), isCancelAfterEnd() etc) should be put onto your Angular component and will work as normal.

Example: Cell Editing using Angular Components

Using Angular Components in the Cell Editors, illustrating keyboard events, rendering, validation and lifecycle events.