@progress/kendo-angular-grid
Version:
Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.
152 lines (151 loc) • 7.21 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Directive, Input } from '@angular/core';
import { GridComponent } from '../grid.component';
import { LocalDataChangesService } from '../editing/local-data-changes.service';
import { markAllAsTouched } from './utils';
import { EditingDirectiveBase } from './editing-directive-base';
import { DialogFormComponent } from '../editing/form';
import { isPresent } from '@progress/kendo-angular-common';
import { AdaptiveGridService } from '../common/adaptiveness.service';
import * as i0 from "@angular/core";
import * as i1 from "../grid.component";
import * as i2 from "../editing/local-data-changes.service";
import * as i3 from "../common/adaptiveness.service";
/**
* Represents the Kendo UI Grid external editing directive. The directive manages editing operations in the Grid when using the
* External Form ([see example](slug:external_editing_grid#quick-setup)).
*
* @example
* ```typescript
* <kendo-grid [data]="data" kendoGridExternalEditing></kendo-grid>
* ```
* @remarks
* Applied to: {@link GridComponent}.
*/
export class ExternalEditingDirective extends EditingDirectiveBase {
grid;
localDataChangesService;
adaptiveGridService;
/**
* Specifies the function that creates the `FormGroup` for the edited model.
*/
createFormGroup;
/**
* Customizes form orientation, hints, labels, and error messages.
*/
formSettings;
/**
* Customizes the Dialog that contains the edit form.
*/
dialogSettings;
constructor(grid, localDataChangesService, adaptiveGridService) {
super(grid, localDataChangesService);
this.grid = grid;
this.localDataChangesService = localDataChangesService;
this.adaptiveGridService = adaptiveGridService;
}
ngOnInit() {
super.ngOnInit();
this.subscriptions
.add(this.grid.edit.subscribe(this.editHandler.bind(this)));
}
/**
* @hidden
* Opens a Dialog that contains the edit form.
*/
openEditFormDialog(editEventArgs, formGroup, formSettings) {
const formControls = this.normalizeFormSettings(formGroup, editEventArgs);
if (this.grid.adaptiveMode === 'auto' && this.adaptiveGridService.windowSize !== 'large') {
if (!this.grid.isActionSheetExpanded) {
this.adaptiveGridService.viewType = 'externalEditing';
this.grid.adaptiveRenderer.externalEditingSettings = { formControls, formGroup, formSettings, event: editEventArgs, externalEditingDirective: this };
this.grid.adaptiveRenderer.actionSheet.toggle(true);
}
}
else {
const settings = { appendTo: this.grid.dialogContainer, content: DialogFormComponent, title: this.localization.get('externalEditingTitle'), ...this.dialogSettings };
const dialog = this.dialogService.open(settings);
this.adaptiveGridService.popupRef = dialog;
dialog.content.setInput('controls', formControls);
formSettings && dialog.content.setInput('formSettings', formSettings);
dialog.content.setInput('formGroup', formGroup);
dialog.result.subscribe((r) => {
const resultType = r['text'];
if (resultType === this.localization.get('externalEditingSaveText')) {
this.saveHandler({ ...editEventArgs, formGroup });
}
dialog.close();
});
}
}
createModel(args) {
return this.createFormGroup(args);
}
editHandler(args) {
const formGroup = this.createModel(args);
this.openEditFormDialog(args, formGroup, this.formSettings);
}
saveModel({ dataItem, formGroup, isNew }) {
if (!formGroup.dirty && !isNew) {
return;
}
if (formGroup.valid) {
const item = dataItem || [];
this.editService.assignValues(item, formGroup.value);
return item;
}
markAllAsTouched(formGroup);
}
addHandler(args) {
const formGroup = this.createModel(args);
this.openEditFormDialog(args, formGroup, this.formSettings);
}
normalizeFormSettings(args, editEventArgs) {
const editableColumnFields = this.grid.columns.toArray().filter(c => c.field && c.editable && isPresent(args.get(c.field))).map(c => c.field);
const settings = editableColumnFields.map(k => {
const column = this.grid.columns.toArray().find(c => c.field === k);
const title = column.title || k;
const template = column.editTemplateRef;
const templateContext = template ? {
$implicit: args,
isNew: editEventArgs.isNew,
column,
dataItem: editEventArgs.dataItem,
formGroup: args,
rowIndex: editEventArgs.rowIndex
} : null;
const customSettings = this.formSettings?.fields?.[k];
return {
name: k,
label: customSettings?.label || title,
hint: customSettings?.hint,
errors: customSettings?.errors,
formControl: args.get(k),
dataType: column.editor,
orientation: this.formSettings?.orientation || 'vertical',
template: template,
templateContext: templateContext
};
});
return settings.filter(item => isPresent(item));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExternalEditingDirective, deps: [{ token: i1.GridComponent }, { token: i2.LocalDataChangesService }, { token: i3.AdaptiveGridService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ExternalEditingDirective, isStandalone: true, selector: "[kendoGridExternalEditing]", inputs: { createFormGroup: ["kendoGridExternalEditing", "createFormGroup"], formSettings: "formSettings", dialogSettings: "dialogSettings" }, usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExternalEditingDirective, decorators: [{
type: Directive,
args: [{
selector: '[kendoGridExternalEditing]',
standalone: true
}]
}], ctorParameters: () => [{ type: i1.GridComponent }, { type: i2.LocalDataChangesService }, { type: i3.AdaptiveGridService }], propDecorators: { createFormGroup: [{
type: Input,
args: ['kendoGridExternalEditing']
}], formSettings: [{
type: Input
}], dialogSettings: [{
type: Input
}] } });