Cell Editor Component
Custom Cell Editor Component
- The provided cell editors are adequate
- But, we can build custom cell editors to meet the user requirements of our applications
- We can leverage a framework such as React, Angular, or Vue.
Goals:
- Build a custom date cell editor component using Angular.
- Use Angular Material's date picker component.
Before we create the component, let's look at the ICellEditorAngularComp interface that establishes the code contract between our custom component and AG Grid.
interface ICellEditorAngularComp {
agInit(params: T): void;
getValue(): any;
isPopup?(): boolean;
}
Let's review each method:
agInit- invoked when the cell editor is created by AG Grid with theICellEditorParamsobject.getValue()- invoked once after editing is complete to provide the value to the grid.isPopup()- optional to control the appearance of the editor as either inline or a popup.
Ok, let's create a custom cell editor using the Material date picker.
export class DateEditorComponent<T = any>
implements ICellEditorAngularComp, AfterViewInit
{
/** The form control for the datepicker input. */
dateControl = new FormControl('');
/** The Material datepicker component. */
@ViewChild(MatDatepicker, { static: true })
datepicker: MatDatepicker<Date>;
/** The cell editor parameters. */
private params: ICellEditorParams<T>;
/** RxJS Subscription. */
private subscription: Subscription;
/** The datepicker value. */
private value: Date;
agInit(params: ICellEditorParams<T>): void {
this.params = params;
this.value = params.value;
this.dateControl.setValue(params.value, { emitEvent: false });
}
ngOnInit(): void {
this.subscription = this.dateControl.valueChanges.subscribe({
error: console.error,
next: (value) => {
this.value = new Date(value);
this.params.stopEditing();
},
});
}
ngAfterViewInit(): void {
this.datepicker.open();
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
getValue(): any {
return this.value;
}
}
Let's review the class properties first:
dateControl- aFormControlfor the date picker input.datePicker- a reference to theMatDatePickerin the template. We'll use this to immediately open the date picker when the component is rendered.params- a reference to theICellEditorParamsobject.subscription- a reference to an RxJS subscription.value- the currentDatevalue of the cell.
Now, let's review the class methods:
agInit- invoked by AG Grid when the cell editor is initialized with the providedICellEditorParamsobject. We'll store a reference to theparamsandvalue, and also invoke thesetValue()method on theFormControlinstance.ngOnInit- subscribe to thevalueChangesObservable. We store thevalueand invoke the providedstopEditir()method using the Grid API to close the editor when a next notification is emittedngAfterviewInit- immediately open the date picker.ngOnDestroy- unsubscribe from the RxJS subscription.getValue- returns thevaluewhen editing is complete.
Registering the component
There are two choices for registering components.
- Provide the Class reference in the column definition
- Register the component using a string constant. This provides the benefit of serialization of the column definition.
Finally, let's register and use the custom DateEditorComponent.
export class GridComponent {
columnDefs = [
{
headerName: 'Date of Order',
field: 'dateOfOrder',
filter: 'agDateColumnFilter',
editable: true,
cellEditor: DateEditorComponent,
},
] as ColDef<RowData>[];
}
Exercise
- Open the exercise on Stackblitz.
- Implement the
agOnInitmethod, storing a reference to theparamsand setting thecheckedproperty based on thevalueprovided. - The
onChange()method is invoked with the slide toggle value changes. In this method, set thecheckedproperty from the providedMatSlideToggleChangeobject. Use the providedstopEditing()Grid API method to stop the editing. - Implement the
getValuemethod.
Solution
@Component({
standalone: true,
imports: [AgGridModule, CommonModule, MatSlideToggleModule],
template: `
<mat-slide-toggle
[checked]="checked"
(change)="onChange($event)"
></mat-slide-toggle>
`,
})
export class SlideToggleEditorComponent<T = any>
implements ICellEditorAngularComp
{
/** Boolean indicating if the slide toggle is on/off. */
checked: boolean;
/** The cell editor parameters. */
private params: ICellEditorParams<T>;
agInit(params: ICellEditorParams<T>): void {
this.params = params;
this.checked = params.value;
}
onChange(matSlideToggleChange: MatSlideToggleChange): void {
this.checked = matSlideToggleChange.checked;
this.params.stopEditing();
}
getValue(): any {
return this.checked;
}
}