diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts index b9979bde06..d967ae74c9 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -22,7 +22,7 @@ import { EllipsisDirective } from './directives/ellipsis.directive'; import { AutofocusDirective } from './directives/autofocus.directive'; import { InputEventDebounceDirective } from './directives/debounce.directive'; import { ClickEventStopPropagationDirective } from './directives/stop-propagation.directive'; -import { FormKeyupListenerDirective } from './directives/form-keyup-listener.directive'; +import { FormSubmitDirective } from './directives/form-submit.directive'; @NgModule({ imports: [ @@ -40,7 +40,7 @@ import { FormKeyupListenerDirective } from './directives/form-keyup-listener.dir DynamicLayoutComponent, AutofocusDirective, EllipsisDirective, - FormKeyupListenerDirective, + FormSubmitDirective, LocalizationPipe, PermissionDirective, VisibilityDirective, @@ -57,7 +57,7 @@ import { FormKeyupListenerDirective } from './directives/form-keyup-listener.dir DynamicLayoutComponent, AutofocusDirective, EllipsisDirective, - FormKeyupListenerDirective, + FormSubmitDirective, LocalizationPipe, PermissionDirective, VisibilityDirective, diff --git a/npm/ng-packs/packages/core/src/lib/directives/form-keyup-listener.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/form-keyup-listener.directive.ts deleted file mode 100644 index 2c9b5d3410..0000000000 --- a/npm/ng-packs/packages/core/src/lib/directives/form-keyup-listener.directive.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Directive, ElementRef, EventEmitter, Output, OnDestroy } from '@angular/core'; -import { fromEvent } from 'rxjs'; -import { debounceTime, filter, tap } from 'rxjs/operators'; -import { takeUntilDestroy } from '../utils/rxjs-utils'; - -@Directive({ - selector: 'form[ngSubmit]', -}) -export class FormKeyupListenerDirective implements OnDestroy { - @Output() ngSubmit = new EventEmitter(); - - constructor(private elRef: ElementRef) { - fromEvent(elRef.nativeElement as HTMLElement, 'keyup') - .pipe( - debounceTime(200), - filter((key: KeyboardEvent) => key && key.key === 'Enter'), - takeUntilDestroy(this), - ) - .subscribe(() => this.ngSubmit.emit()); - } - - ngOnDestroy(): void {} -} diff --git a/npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts new file mode 100644 index 0000000000..1672e6099a --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/directives/form-submit.directive.ts @@ -0,0 +1,78 @@ +import { + Directive, + ElementRef, + OnDestroy, + OnInit, + Self, + ChangeDetectorRef, + HostBinding, + Input, + Output, + EventEmitter, +} from '@angular/core'; +import { FormGroupDirective, FormGroup, FormControl, ɵNgNoValidate } from '@angular/forms'; +import { fromEvent } from 'rxjs'; +import { takeUntilDestroy } from '../utils'; +import { debounceTime, filter } from 'rxjs/operators'; + +type Controls = { [key: string]: FormControl } | FormGroup[]; + +@Directive({ + selector: 'form[ngSubmit][formGroup]', +}) +export class FormSubmitDirective implements OnInit, OnDestroy { + @Input() + noValidateOnSubmit; + + @Input() + allowSubmit: boolean = true; + + constructor( + @Self() private formGroupDirective: FormGroupDirective, + private host: ElementRef, + private cdRef: ChangeDetectorRef, + ) {} + + ngOnInit() { + fromEvent(this.host.nativeElement as HTMLElement, 'keyup') + .pipe( + debounceTime(200), + filter((key: KeyboardEvent) => key && key.key === 'Enter' && this.allowSubmit), + takeUntilDestroy(this), + ) + .subscribe(() => { + this.host.nativeElement.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); + }); + + if (this.noValidateOnSubmit || typeof this.noValidateOnSubmit === 'string') { + return; + } + + fromEvent(this.host.nativeElement, 'submit') + .pipe(takeUntilDestroy(this)) + .subscribe(() => { + const { form } = this.formGroupDirective; + + setDirty(form.controls as { [key: string]: FormControl }); + form.markAsDirty(); + + this.cdRef.detectChanges(); + }); + } + + ngOnDestroy(): void {} +} + +function setDirty(controls: Controls) { + if (Array.isArray(controls)) { + controls.forEach(group => { + setDirty(group.controls as { [key: string]: FormControl }); + }); + return; + } + + Object.keys(controls).forEach(key => { + controls[key].markAsDirty(); + controls[key].updateValueAndValidity(); + }); +} diff --git a/npm/ng-packs/packages/core/src/lib/directives/index.ts b/npm/ng-packs/packages/core/src/lib/directives/index.ts index d3da66bed4..336b6ff5ab 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/index.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/index.ts @@ -1,5 +1,5 @@ export * from './autofocus.directive'; export * from './ellipsis.directive'; -export * from './form-keyup-listener.directive'; +export * from './form-submit.directive'; export * from './permission.directive'; export * from './visibility.directive'; diff --git a/npm/ng-packs/packages/theme-shared/package.json b/npm/ng-packs/packages/theme-shared/package.json index a71bc08def..6ed4fbe8eb 100644 --- a/npm/ng-packs/packages/theme-shared/package.json +++ b/npm/ng-packs/packages/theme-shared/package.json @@ -5,7 +5,7 @@ "@abp/ng.core": "^0.8.3", "@angular/cdk": "^8.0.1", "@ng-bootstrap/ng-bootstrap": "^5.1.0", - "@ngx-validate/core": "^0.0.4", + "@ngx-validate/core": "^0.0.5", "bootstrap": "^4.3.1", "font-awesome": "^4.7.0", "ngx-perfect-scrollbar": "^8.0.0",