@stemy/ngx-dynamic-form 19.0.9 → 19.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/stemy-ngx-dynamic-form.mjs +108 -89
- package/fesm2022/stemy-ngx-dynamic-form.mjs.map +1 -1
- package/ngx-dynamic-form/common-types.d.ts +3 -4
- package/ngx-dynamic-form/ngx-dynamic-form.imports.d.ts +1 -1
- package/ngx-dynamic-form/ngx-dynamic-form.module.d.ts +3 -1
- package/ngx-dynamic-form/services/dynamic-form.service.d.ts +8 -9
- package/package.json +1 -1
- package/public_api.d.ts +1 -1
|
@@ -7,7 +7,7 @@ import { __decorate } from 'tslib';
|
|
|
7
7
|
import { BehaviorSubject, isObservable, of, Subject, firstValueFrom, Subscription } from 'rxjs';
|
|
8
8
|
import { map, debounceTime, first, groupBy, mergeMap } from 'rxjs/operators';
|
|
9
9
|
import * as i0 from '@angular/core';
|
|
10
|
-
import { Injector, Injectable, Inject, EventEmitter, Directive, Input, Output, HostBinding, HostListener, QueryList, Component, ChangeDetectionStrategy, ContentChildren, ViewChildren, ViewContainerRef, ViewChild, forwardRef, Optional, NgModule } from '@angular/core';
|
|
10
|
+
import { Injector, Injectable, Inject, EventEmitter, Directive, Input, Output, HostBinding, HostListener, QueryList, Component, ChangeDetectionStrategy, ContentChildren, ViewChildren, ViewContainerRef, ViewChild, forwardRef, Optional, makeEnvironmentProviders, NgModule } from '@angular/core';
|
|
11
11
|
import { FormGroup, FormArray, FormsModule, ReactiveFormsModule, NG_VALIDATORS } from '@angular/forms';
|
|
12
12
|
import { CommonModule } from '@angular/common';
|
|
13
13
|
|
|
@@ -541,24 +541,43 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
541
541
|
this.openApi = openApi;
|
|
542
542
|
this.injector = injector;
|
|
543
543
|
}
|
|
544
|
+
async serializeForm(form, validate) {
|
|
545
|
+
if (!form.group)
|
|
546
|
+
return null;
|
|
547
|
+
if (validate) {
|
|
548
|
+
await this.validateForm(form);
|
|
549
|
+
}
|
|
550
|
+
return this.serialize(form.model, form.group);
|
|
551
|
+
}
|
|
552
|
+
async getFormModelForSchema(name, customizeOrOptions) {
|
|
553
|
+
return (await this.getFormGroupModelForSchema(name, customizeOrOptions)).group;
|
|
554
|
+
}
|
|
555
|
+
getErrors(form) {
|
|
556
|
+
this.showErrors(form);
|
|
557
|
+
return new Promise(resolve => {
|
|
558
|
+
setTimeout(() => {
|
|
559
|
+
resolve(getFormValidationErrors(form.group.controls, ""));
|
|
560
|
+
}, 500);
|
|
561
|
+
});
|
|
562
|
+
}
|
|
544
563
|
createFormGroup(formModel, options, parent) {
|
|
545
564
|
const group = super.createFormGroup(formModel, options, parent);
|
|
546
565
|
if (!parent) {
|
|
547
566
|
group.valueChanges.pipe(debounceTime(500)).subscribe(() => {
|
|
548
|
-
this.notifyChanges(formModel, group);
|
|
567
|
+
this.notifyChanges(formModel, group, formModel);
|
|
549
568
|
});
|
|
550
569
|
}
|
|
551
570
|
return group;
|
|
552
571
|
}
|
|
553
572
|
patchGroup(value, formModel, formGroup) {
|
|
554
573
|
value = ObjectUtils.copy(value);
|
|
555
|
-
this.
|
|
574
|
+
this.patchValues(value, formModel, formGroup);
|
|
556
575
|
formGroup.patchValue(value);
|
|
557
576
|
this.detectChanges();
|
|
558
577
|
}
|
|
559
578
|
patchForm(value, component) {
|
|
560
579
|
value = ObjectUtils.copy(value);
|
|
561
|
-
this.
|
|
580
|
+
this.patchValues(value, component.model, component.group);
|
|
562
581
|
component.group.patchValue(value);
|
|
563
582
|
this.detectChanges(component);
|
|
564
583
|
}
|
|
@@ -580,68 +599,7 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
580
599
|
form.group.updateValueAndValidity();
|
|
581
600
|
});
|
|
582
601
|
}
|
|
583
|
-
async
|
|
584
|
-
if (!form.group)
|
|
585
|
-
return null;
|
|
586
|
-
if (validate) {
|
|
587
|
-
await this.validateForm(form);
|
|
588
|
-
}
|
|
589
|
-
return this.serialize(form.model, form.group);
|
|
590
|
-
}
|
|
591
|
-
serialize(formModel, formGroup) {
|
|
592
|
-
return this.serializeRecursive(formModel, formGroup);
|
|
593
|
-
}
|
|
594
|
-
notifyChanges(formModel, formGroup) {
|
|
595
|
-
this.notifyChangesRecursive(formModel, formGroup, formModel);
|
|
596
|
-
}
|
|
597
|
-
showErrors(form) {
|
|
598
|
-
this.showErrorsForGroup(form.group);
|
|
599
|
-
this.detectChanges(form);
|
|
600
|
-
}
|
|
601
|
-
getErrors(form) {
|
|
602
|
-
this.showErrors(form);
|
|
603
|
-
return new Promise(resolve => {
|
|
604
|
-
setTimeout(() => {
|
|
605
|
-
resolve(getFormValidationErrors(form.group.controls, ""));
|
|
606
|
-
}, 500);
|
|
607
|
-
});
|
|
608
|
-
}
|
|
609
|
-
patchValueRecursive(value, formModel, formGroup) {
|
|
610
|
-
if (!value)
|
|
611
|
-
return;
|
|
612
|
-
formModel?.forEach(subModel => {
|
|
613
|
-
const key = subModel.id;
|
|
614
|
-
const subValue = value[key];
|
|
615
|
-
const subControl = this.findControlByModel(subModel, formGroup);
|
|
616
|
-
if (subModel instanceof DynamicSelectModel && ObjectUtils.isObject(subValue)) {
|
|
617
|
-
value[key] = subValue.id || subValue._id || subValue;
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
if (subModel instanceof DynamicDatePickerModel) {
|
|
621
|
-
value[key] = this.convertToDate(subValue);
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
if (subModel instanceof DynamicFormArrayModel) {
|
|
625
|
-
const length = Array.isArray(subValue) ? subValue.length : 0;
|
|
626
|
-
const subArray = subControl;
|
|
627
|
-
while (subModel.size > length) {
|
|
628
|
-
this.removeFormArrayGroup(0, subArray, subModel);
|
|
629
|
-
}
|
|
630
|
-
while (subModel.size < length) {
|
|
631
|
-
this.insertFormArrayGroup(subModel.size, subArray, subModel);
|
|
632
|
-
}
|
|
633
|
-
for (let i = 0; i < length; i++) {
|
|
634
|
-
const itemModel = subModel.get(i);
|
|
635
|
-
this.patchValueRecursive(subValue[i], itemModel.group, subArray.at(i));
|
|
636
|
-
}
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
if (subModel instanceof DynamicFormGroupModel) {
|
|
640
|
-
this.patchValueRecursive(subValue, subModel.group, subControl);
|
|
641
|
-
}
|
|
642
|
-
});
|
|
643
|
-
}
|
|
644
|
-
async serializeRecursive(formModel, formGroup) {
|
|
602
|
+
async serialize(formModel, formGroup) {
|
|
645
603
|
const result = {};
|
|
646
604
|
if (!formModel || !formGroup || !formGroup.value)
|
|
647
605
|
return result;
|
|
@@ -661,7 +619,7 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
661
619
|
const resArray = [];
|
|
662
620
|
for (let i = 0; i < length; i++) {
|
|
663
621
|
const itemModel = subModel.get(i);
|
|
664
|
-
resArray.push(await this.
|
|
622
|
+
resArray.push(await this.serialize(itemModel.group, subArray.at(i)));
|
|
665
623
|
}
|
|
666
624
|
result[subModel.id] = resArray;
|
|
667
625
|
continue;
|
|
@@ -673,14 +631,18 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
673
631
|
continue;
|
|
674
632
|
}
|
|
675
633
|
if (subModel instanceof DynamicFormGroupModel) {
|
|
676
|
-
result[subModel.id] = await this.
|
|
634
|
+
result[subModel.id] = await this.serialize(subModel.group, subControl);
|
|
677
635
|
continue;
|
|
678
636
|
}
|
|
679
637
|
result[subModel.id] = subControl.value;
|
|
680
638
|
}
|
|
681
639
|
return result;
|
|
682
640
|
}
|
|
683
|
-
|
|
641
|
+
showErrors(form) {
|
|
642
|
+
this.showErrorsForGroup(form.group);
|
|
643
|
+
this.detectChanges(form);
|
|
644
|
+
}
|
|
645
|
+
notifyChanges(formModel, formGroup, root) {
|
|
684
646
|
if (!formModel || !formGroup)
|
|
685
647
|
return;
|
|
686
648
|
for (const i in formModel) {
|
|
@@ -691,17 +653,52 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
691
653
|
const subArray = subControl;
|
|
692
654
|
for (let i = 0; i < length; i++) {
|
|
693
655
|
const itemModel = subModel.get(i);
|
|
694
|
-
this.
|
|
656
|
+
this.notifyChanges(itemModel.group, subArray.at(i), root);
|
|
695
657
|
}
|
|
696
658
|
continue;
|
|
697
659
|
}
|
|
698
660
|
if (subModel instanceof DynamicFormGroupModel) {
|
|
699
|
-
this.
|
|
661
|
+
this.notifyChanges(subModel.group, subControl, root);
|
|
700
662
|
continue;
|
|
701
663
|
}
|
|
702
664
|
this.updateSelectOptions(subModel, subControl, root);
|
|
703
665
|
}
|
|
704
666
|
}
|
|
667
|
+
patchValues(value, formModel, formGroup) {
|
|
668
|
+
if (!value)
|
|
669
|
+
return;
|
|
670
|
+
formModel?.forEach(subModel => {
|
|
671
|
+
const key = subModel.id;
|
|
672
|
+
const subValue = value[key];
|
|
673
|
+
const subControl = this.findControlByModel(subModel, formGroup);
|
|
674
|
+
if (subModel instanceof DynamicSelectModel && ObjectUtils.isObject(subValue)) {
|
|
675
|
+
value[key] = subValue.id || subValue._id || subValue;
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
if (subModel instanceof DynamicDatePickerModel) {
|
|
679
|
+
value[key] = this.convertToDate(subValue);
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
if (subModel instanceof DynamicFormArrayModel) {
|
|
683
|
+
const length = Array.isArray(subValue) ? subValue.length : 0;
|
|
684
|
+
const subArray = subControl;
|
|
685
|
+
while (subModel.size > length) {
|
|
686
|
+
this.removeFormArrayGroup(0, subArray, subModel);
|
|
687
|
+
}
|
|
688
|
+
while (subModel.size < length) {
|
|
689
|
+
this.insertFormArrayGroup(subModel.size, subArray, subModel);
|
|
690
|
+
}
|
|
691
|
+
for (let i = 0; i < length; i++) {
|
|
692
|
+
const itemModel = subModel.get(i);
|
|
693
|
+
this.patchValues(subValue[i], itemModel.group, subArray.at(i));
|
|
694
|
+
}
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
if (subModel instanceof DynamicFormGroupModel) {
|
|
698
|
+
this.patchValues(subValue, subModel.group, subControl);
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
}
|
|
705
702
|
updateSelectOptions(formControlModel, formControl, root) {
|
|
706
703
|
if (formControlModel instanceof DynamicSelectModel) {
|
|
707
704
|
let options = formControlModel.options$;
|
|
@@ -744,14 +741,17 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
744
741
|
: new Date(value);
|
|
745
742
|
return isNaN(date) ? new Date() : date;
|
|
746
743
|
}
|
|
747
|
-
async
|
|
748
|
-
return (await this.getFormGroupModelForSchema(name, customizeModel)).group;
|
|
749
|
-
}
|
|
750
|
-
async getFormGroupModelForSchema(name, customizeModel) {
|
|
744
|
+
async getFormGroupModelForSchema(name, customizeOrOptions) {
|
|
751
745
|
this.api.cache = {};
|
|
752
746
|
this.schemas = await this.openApi.getSchemas();
|
|
753
747
|
const fieldSets = [];
|
|
748
|
+
const options = ObjectUtils.isObject(customizeOrOptions) ? customizeOrOptions : {};
|
|
749
|
+
const customizeModel = ObjectUtils.isFunction(customizeOrOptions)
|
|
750
|
+
? customizeOrOptions : options.customizer;
|
|
754
751
|
const customizeModels = async (property, schema, modelType, config) => {
|
|
752
|
+
config.label = !config.label || !options.labelPrefix
|
|
753
|
+
? config.label || ""
|
|
754
|
+
: await this.language.getTranslation(`${options.labelPrefix}.${config.label}`);
|
|
755
755
|
const model = new modelType(config);
|
|
756
756
|
if (model instanceof DynamicFormValueControlModel) {
|
|
757
757
|
model.value = (model instanceof DynamicDatePickerModel)
|
|
@@ -1044,7 +1044,7 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
1044
1044
|
return new FormSelectSubject(async (selectModel, control) => {
|
|
1045
1045
|
const entries = Object.entries(control.root?.controls || {});
|
|
1046
1046
|
const endpoint = entries.reduce((res, [key, control]) => {
|
|
1047
|
-
return
|
|
1047
|
+
return this.replaceOptionsEndpoint(res, key, control?.value);
|
|
1048
1048
|
}, `${property.endpoint}`);
|
|
1049
1049
|
this.api.cache[endpoint] = this.api.cache[endpoint] || this.api.list(endpoint, this.api.makeListParams(1, -1)).then(result => {
|
|
1050
1050
|
const items = ObjectUtils.isArray(result)
|
|
@@ -1095,6 +1095,19 @@ class DynamicFormService extends DynamicFormService$1 {
|
|
|
1095
1095
|
this.patchGroup(formArray.at(index + 1).value, formArrayModel.groups[index].group, formArray.at(index));
|
|
1096
1096
|
formArrayModel.filterGroups();
|
|
1097
1097
|
}
|
|
1098
|
+
replaceOptionsEndpoint(endpoint, key, value) {
|
|
1099
|
+
if (ObjectUtils.isObject(value)) {
|
|
1100
|
+
return Object.entries(value).reduce((res, [k, v]) => {
|
|
1101
|
+
return this.replaceOptionsEndpoint(res, `${key}.${k}`, v);
|
|
1102
|
+
}, endpoint);
|
|
1103
|
+
}
|
|
1104
|
+
if (ObjectUtils.isArray(value)) {
|
|
1105
|
+
return value.reduce((res, v, i) => {
|
|
1106
|
+
return this.replaceOptionsEndpoint(res, `${key}.${i}`, v);
|
|
1107
|
+
}, endpoint);
|
|
1108
|
+
}
|
|
1109
|
+
return endpoint.replace(new RegExp(`\\$${key}`, "gi"), `${value ?? ""}`);
|
|
1110
|
+
}
|
|
1098
1111
|
async fixSelectOptions(model, control, options) {
|
|
1099
1112
|
if (!options)
|
|
1100
1113
|
return [];
|
|
@@ -1347,7 +1360,7 @@ class DynamicBaseFormComponent extends DynamicFormComponent {
|
|
|
1347
1360
|
this.templates.reset(templates);
|
|
1348
1361
|
}
|
|
1349
1362
|
}), this.events.languageChanged.subscribe(() => {
|
|
1350
|
-
this.formService.notifyChanges(this.model, this.group);
|
|
1363
|
+
this.formService.notifyChanges(this.model, this.group, this.model);
|
|
1351
1364
|
this.formService.detectChanges(this);
|
|
1352
1365
|
}));
|
|
1353
1366
|
}
|
|
@@ -1902,23 +1915,29 @@ function defaultFormControlProvider() {
|
|
|
1902
1915
|
}
|
|
1903
1916
|
|
|
1904
1917
|
class NgxDynamicFormModule {
|
|
1918
|
+
static getProviders(config) {
|
|
1919
|
+
return [
|
|
1920
|
+
DynamicFormService,
|
|
1921
|
+
{
|
|
1922
|
+
provide: DynamicFormService$1,
|
|
1923
|
+
useExisting: DynamicFormService
|
|
1924
|
+
},
|
|
1925
|
+
{
|
|
1926
|
+
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
|
1927
|
+
useFactory: (config?.controlProvider || defaultFormControlProvider),
|
|
1928
|
+
deps: [Injector]
|
|
1929
|
+
}
|
|
1930
|
+
];
|
|
1931
|
+
}
|
|
1905
1932
|
static forRoot(config) {
|
|
1906
1933
|
return {
|
|
1907
1934
|
ngModule: NgxDynamicFormModule,
|
|
1908
|
-
providers:
|
|
1909
|
-
DynamicFormService,
|
|
1910
|
-
{
|
|
1911
|
-
provide: DynamicFormService$1,
|
|
1912
|
-
useExisting: DynamicFormService
|
|
1913
|
-
},
|
|
1914
|
-
{
|
|
1915
|
-
provide: DYNAMIC_FORM_CONTROL_MAP_FN,
|
|
1916
|
-
useFactory: (config?.controlProvider || defaultFormControlProvider),
|
|
1917
|
-
deps: [Injector]
|
|
1918
|
-
}
|
|
1919
|
-
]
|
|
1935
|
+
providers: NgxDynamicFormModule.getProviders(config)
|
|
1920
1936
|
};
|
|
1921
1937
|
}
|
|
1938
|
+
static provideForms(config) {
|
|
1939
|
+
return makeEnvironmentProviders(NgxDynamicFormModule.getProviders(config));
|
|
1940
|
+
}
|
|
1922
1941
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: NgxDynamicFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1923
1942
|
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: NgxDynamicFormModule, declarations: [DynamicBaseFormComponent, DynamicBaseFormArrayComponent, DynamicBaseFormControlComponent, DynamicBaseFormControlContainerComponent, DynamicBaseFormGroupComponent, DynamicBaseSelectComponent, AsyncSubmitDirective], imports: [CommonModule,
|
|
1924
1943
|
FormsModule,
|