import { ChangeDetectorRef, Component, ContentChild, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges, SkipSelf } from "@angular/core"; import {FormGroup, NgControl} from "@angular/forms"; import {detectChangesNextFrame} from "../app"; @Component({ selector: 'dui-form-row', template: `
{{label}}
{{isString(kv.value) ? '' : kv.key}}{{isString(kv.value) ? kv.value : ''}}
`, styleUrls: ['./form-row.component.scss'] }) export class FormRowComponent { @Input() label: string = ''; @ContentChild(NgControl, {static: false}) ngControl?: NgControl; isString(v: any){ return 'string' === typeof v; } } @Component({ selector: 'dui-form', template: `
{{errorText}}
`, styleUrls: ['./form.component.scss'] }) export class FormComponent implements OnChanges { @Input() formGroup: FormGroup = new FormGroup({}); @Input() disabled: boolean = false; @Input() submit?: () => Promise | any; @Output() success = new EventEmitter(); @Output() error = new EventEmitter(); @Output() disableChange = new EventEmitter(); public errorText = ''; public submitting = false; constructor( protected cd: ChangeDetectorRef, @SkipSelf() protected cdParent: ChangeDetectorRef, ) { } @HostListener('keyup', ['$event']) onEnter(event: KeyboardEvent) { if (this.submit && event.key.toLowerCase() === 'enter' && event.target && (event.target as HTMLElement).tagName.toLowerCase() === 'input') { this.submitForm(); } } ngOnChanges(changes: SimpleChanges) { if (changes.disabled) { this.disableChange.emit(this.disabled); } } get invalid() { return this.formGroup.invalid; } async submitForm() { if (this.disabled) return; if (this.submitting) return; if (this.formGroup.invalid) return; this.errorText = ''; this.submitting = true; detectChangesNextFrame(this.cd); try { if (this.submit) { try { await this.submit(); this.success.emit(); } catch (error) { this.error.emit(error); if (error.errors && error.errors[0]) { //we got a validation-like error object for (const item of error.errors) { const control = this.formGroup.get(item.path); if (control) { control.setErrors({ ...control.errors, [item.code]: item.message, }); } } } else { this.errorText = error.message || error; } console.log('form error', error); } } } finally { this.submitting = false; detectChangesNextFrame(this.cd); } } }