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 theICellEditorParams
object.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
- aFormControl
for the date picker input.datePicker
- a reference to theMatDatePicker
in the template. We'll use this to immediately open the date picker when the component is rendered.params
- a reference to theICellEditorParams
object.subscription
- a reference to an RxJS subscription.value
- the currentDate
value of the cell.
Now, let's review the class methods:
agInit
- invoked by AG Grid when the cell editor is initialized with the providedICellEditorParams
object. We'll store a reference to theparams
andvalue
, and also invoke thesetValue()
method on theFormControl
instance.ngOnInit
- subscribe to thevalueChanges
Observable. We store thevalue
and 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 thevalue
when 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
agOnInit
method, storing a reference to theparams
and setting thechecked
property based on thevalue
provided. - The
onChange()
method is invoked with the slide toggle value changes. In this method, set thechecked
property from the providedMatSlideToggleChange
object. Use the providedstopEditing()
Grid API method to stop the editing. - Implement the
getValue
method.
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;
}
}