@stemy/ngx-dynamic-form 19.9.12 → 19.9.13
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.
|
@@ -1337,13 +1337,23 @@ class DynamicFormSchemaService {
|
|
|
1337
1337
|
}, parent, options);
|
|
1338
1338
|
}
|
|
1339
1339
|
getFormSelectOptions($enum, property, options, field) {
|
|
1340
|
-
|
|
1341
|
-
|
|
1340
|
+
// --- Handle options from another property path ---
|
|
1341
|
+
if (ObjectUtils.isStringWithValue(property.optionsPath)) {
|
|
1342
|
+
return this.getFormPathOptions(property.optionsPath, field);
|
|
1342
1343
|
}
|
|
1344
|
+
// --- Handle options from an endpoint ---
|
|
1343
1345
|
if (ObjectUtils.isStringWithValue(property.endpoint)) {
|
|
1344
1346
|
return this.getFormEndpointOptions(property, field);
|
|
1345
1347
|
}
|
|
1346
|
-
|
|
1348
|
+
// --- Handle direct options like an enum ---
|
|
1349
|
+
if (Array.isArray(property.options)) {
|
|
1350
|
+
return this.getFormEnumOptions(property.options, property.id, options, field);
|
|
1351
|
+
}
|
|
1352
|
+
// --- Handle enum options ---
|
|
1353
|
+
if (Array.isArray($enum)) {
|
|
1354
|
+
return this.getFormEnumOptions($enum, property.id, options, field);
|
|
1355
|
+
}
|
|
1356
|
+
return [];
|
|
1347
1357
|
}
|
|
1348
1358
|
getFormEnumOptions($enum, id, options, field) {
|
|
1349
1359
|
return this.builder.language.pipe(distinctUntilChanged(), switchMap(async () => {
|
|
@@ -1497,20 +1507,30 @@ class DynamicFormService {
|
|
|
1497
1507
|
return this.getFormFieldGroupBySchemaName(name, customizeOrOptions, "getFormFieldsForSchema");
|
|
1498
1508
|
}
|
|
1499
1509
|
async getFormFieldGroupBySchemaName(name, customizeOrOptions, restrictedMethod) {
|
|
1500
|
-
const config = {
|
|
1501
|
-
id: FORM_ROOT_ID,
|
|
1502
|
-
path: "",
|
|
1503
|
-
wrappers: ["form-group"],
|
|
1504
|
-
props: {}
|
|
1505
|
-
};
|
|
1506
1510
|
const schema = await this.fs.getSchema(name);
|
|
1507
1511
|
if (!schema) {
|
|
1508
1512
|
console.warn(`Schema with name "${name}" not found.`);
|
|
1509
|
-
return
|
|
1513
|
+
return {
|
|
1514
|
+
id: FORM_ROOT_ID,
|
|
1515
|
+
path: "",
|
|
1516
|
+
wrappers: ["form-group"],
|
|
1517
|
+
fieldGroup: [],
|
|
1518
|
+
props: {},
|
|
1519
|
+
hooks: {},
|
|
1520
|
+
expressions: {}
|
|
1521
|
+
};
|
|
1510
1522
|
}
|
|
1511
1523
|
const wrapOptions = await toWrapOptions(customizeOrOptions, this.injector, schema, `"DynamicFormService.${restrictedMethod}" is called from a customizer, which is not allowed. Please use DynamicFormSchemaService instead!`);
|
|
1512
|
-
const
|
|
1524
|
+
const config = await this.fb.createFormGroup(null, parent => {
|
|
1525
|
+
return this.fs.getFormFieldsForSchema(schema, parent, wrapOptions);
|
|
1526
|
+
}, {
|
|
1527
|
+
label: "",
|
|
1528
|
+
hidden: false,
|
|
1529
|
+
className: "dynamic-form-root-group"
|
|
1530
|
+
}, null, wrapOptions);
|
|
1531
|
+
const fields = config.fieldGroup || [];
|
|
1513
1532
|
const fieldGroup = [...fields];
|
|
1533
|
+
config.id = FORM_ROOT_ID;
|
|
1514
1534
|
config.fieldGroup = fieldGroup;
|
|
1515
1535
|
// There are no actual fields in the schema, or no schema exists
|
|
1516
1536
|
if (fields.length === 0)
|
|
@@ -2023,16 +2043,16 @@ class DynamicFormComponent {
|
|
|
2023
2043
|
legacyLabels: this.legacyLabels(),
|
|
2024
2044
|
testId: this.testId(),
|
|
2025
2045
|
};
|
|
2026
|
-
const
|
|
2046
|
+
const defs = this.fields();
|
|
2047
|
+
const fields = Array.isArray(defs) ? defs : null;
|
|
2027
2048
|
const constructor = this.data()?.constructor;
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
];
|
|
2049
|
+
const root = (Array.isArray(defs) ? null : defs) ?? this.builder.createFormGroup(null, parent => this.builder.createFieldSets(fields ?? this.builder.resolveFormFields(constructor, parent, options), parent), {
|
|
2050
|
+
label: "",
|
|
2051
|
+
hidden: false,
|
|
2052
|
+
useTabs: this.useTabs(),
|
|
2053
|
+
className: "dynamic-form-root-group"
|
|
2054
|
+
});
|
|
2055
|
+
return [root];
|
|
2036
2056
|
});
|
|
2037
2057
|
group = computed(() => {
|
|
2038
2058
|
this.config();
|
|
@@ -2254,11 +2274,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImpo
|
|
|
2254
2274
|
|
|
2255
2275
|
class DynamicFormGroupComponent extends FieldWrapper {
|
|
2256
2276
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: DynamicFormGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2257
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: DynamicFormGroupComponent, isStandalone: false, selector: "dynamic-form-group", usesInheritance: true, ngImport: i0, template: "<ng-template #innerLabelTemplate let-label=\"label\">\n <label class=\"field-label\" [for]=\"id\">\n <span [innerHTML]=\"label | safe: 'html'\"></span>\n @if (props.markRequired) {\n <span class=\"field-required\" aria-hidden=\"true\">*</span>\n }\n @if (props.description) {\n <p class=\"field-description\" [innerHTML]=\"props.description | translate | safe: 'html'\"></p>\n }\n </label>\n</ng-template>\n<ng-template #labelTemplate>\n @let label = !props.label || props.hideLabel ? null : props.label | translate;\n @if (label) {\n <ng-container [ngxTemplateOutlet]=\"(field | dynamicFormTemplate : 'label') || innerLabelTemplate\"\n [context]=\"field\"\n [additionalContext]=\"{label: label}\"></ng-container>\n }\n</ng-template>\n@if (field.display) {\n @if (props.labelAlign === \"before\") {\n <ng-container [ngTemplateOutlet]=\"labelTemplate\"></ng-container>\n }\n <tabs class=\"field-container\">\n @for (itemField of field.fieldGroup; track itemField
|
|
2277
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: DynamicFormGroupComponent, isStandalone: false, selector: "dynamic-form-group", usesInheritance: true, ngImport: i0, template: "<ng-template #innerLabelTemplate let-label=\"label\">\n <label class=\"field-label\" [for]=\"id\">\n <span [innerHTML]=\"label | safe: 'html'\"></span>\n @if (props.markRequired) {\n <span class=\"field-required\" aria-hidden=\"true\">*</span>\n }\n @if (props.description) {\n <p class=\"field-description\" [innerHTML]=\"props.description | translate | safe: 'html'\"></p>\n }\n </label>\n</ng-template>\n<ng-template #labelTemplate>\n @let label = !props.label || props.hideLabel ? null : props.label | translate;\n @if (label) {\n <ng-container [ngxTemplateOutlet]=\"(field | dynamicFormTemplate : 'label') || innerLabelTemplate\"\n [context]=\"field\"\n [additionalContext]=\"{label: label}\"></ng-container>\n }\n</ng-template>\n@if (field.display) {\n @if (props.labelAlign === \"before\") {\n <ng-container [ngTemplateOutlet]=\"labelTemplate\"></ng-container>\n }\n <tabs class=\"field-container\" [testId]=\"(field.testId || 'form') + '-tab'\">\n @for (itemField of field.fieldGroup; track itemField) {\n @if (itemField.display) {\n @if (props.useTabs && itemField.wrappers | includes: 'form-fieldset') {\n <div class=\"form-fieldset-item\"\n [tabsItem]=\"itemField.id\"\n [classes]=\"['form-fieldset-tab', itemField.valid === false ? 'invalid' : 'valid']\"\n [label]=\"itemField.props.label\">\n <formly-field [field]=\"itemField\"></formly-field>\n </div>\n } @else {\n <formly-field [field]=\"itemField\"></formly-field>\n }\n }\n }\n @if (showError && field.key !== null) {\n <div *ngIf=\"showError\" class=\"field-errors invalid-feedback\">\n <formly-validation-message\n [field]=\"field\"\n id=\"{{ id }}-formly-validation-error\"\n role=\"alert\"\n ></formly-validation-message>\n </div>\n }\n </tabs>\n @if (props.labelAlign === \"after\") {\n <ng-container [ngTemplateOutlet]=\"labelTemplate\"></ng-container>\n }\n}\n", styles: [".form-fieldset-item.hidden-tab{display:none}.form-fieldset-tab{position:relative;--invalid-bg: rgba(184, 38, 38, 1);--invalid-border: rgba(184, 38, 38, .6);--invalid-color: #ececec;--invalid-box-size: 15px;--invalid-box-pull: -3px}.form-fieldset-tab.invalid>btn .async-target{border:1px solid var(--invalid-border)}.form-fieldset-tab.invalid:after{background:var(--invalid-bg);color:var(--invalid-color);font-size:10px;line-height:var(--invalid-box-size);width:var(--invalid-box-size);height:var(--invalid-box-size);text-align:center;border-radius:5px;content:\"!\";display:block;position:absolute;top:var(--invalid-box-pull);right:var(--invalid-box-pull)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgxTemplateOutletDirective, selector: "[ngxTemplateOutlet]", inputs: ["context", "additionalContext", "ngxTemplateOutlet"] }, { kind: "directive", type: i2.TabsItemDirective, selector: "[tabsItem]", inputs: ["tabsItem", "label", "tooltip", "icon", "disabled", "classes"] }, { kind: "component", type: i2.TabsComponent, selector: "tabs", inputs: ["value", "options", "type", "size", "testId", "tabsClass"], outputs: ["valueChange", "selectedChange"] }, { kind: "component", type: i3.LegacyFormlyField, selector: "formly-field" }, { kind: "component", type: i3.LegacyFormlyValidationMessage, selector: "formly-validation-message" }, { kind: "pipe", type: i2.IncludesPipe, name: "includes" }, { kind: "pipe", type: i2.SafeHtmlPipe, name: "safe" }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "pipe", type: DynamicFormTemplatePipe, name: "dynamicFormTemplate" }], encapsulation: i0.ViewEncapsulation.None });
|
|
2258
2278
|
}
|
|
2259
2279
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: DynamicFormGroupComponent, decorators: [{
|
|
2260
2280
|
type: Component,
|
|
2261
|
-
args: [{ standalone: false, selector: "dynamic-form-group", encapsulation: ViewEncapsulation.None, template: "<ng-template #innerLabelTemplate let-label=\"label\">\n <label class=\"field-label\" [for]=\"id\">\n <span [innerHTML]=\"label | safe: 'html'\"></span>\n @if (props.markRequired) {\n <span class=\"field-required\" aria-hidden=\"true\">*</span>\n }\n @if (props.description) {\n <p class=\"field-description\" [innerHTML]=\"props.description | translate | safe: 'html'\"></p>\n }\n </label>\n</ng-template>\n<ng-template #labelTemplate>\n @let label = !props.label || props.hideLabel ? null : props.label | translate;\n @if (label) {\n <ng-container [ngxTemplateOutlet]=\"(field | dynamicFormTemplate : 'label') || innerLabelTemplate\"\n [context]=\"field\"\n [additionalContext]=\"{label: label}\"></ng-container>\n }\n</ng-template>\n@if (field.display) {\n @if (props.labelAlign === \"before\") {\n <ng-container [ngTemplateOutlet]=\"labelTemplate\"></ng-container>\n }\n <tabs class=\"field-container\">\n @for (itemField of field.fieldGroup; track itemField
|
|
2281
|
+
args: [{ standalone: false, selector: "dynamic-form-group", encapsulation: ViewEncapsulation.None, template: "<ng-template #innerLabelTemplate let-label=\"label\">\n <label class=\"field-label\" [for]=\"id\">\n <span [innerHTML]=\"label | safe: 'html'\"></span>\n @if (props.markRequired) {\n <span class=\"field-required\" aria-hidden=\"true\">*</span>\n }\n @if (props.description) {\n <p class=\"field-description\" [innerHTML]=\"props.description | translate | safe: 'html'\"></p>\n }\n </label>\n</ng-template>\n<ng-template #labelTemplate>\n @let label = !props.label || props.hideLabel ? null : props.label | translate;\n @if (label) {\n <ng-container [ngxTemplateOutlet]=\"(field | dynamicFormTemplate : 'label') || innerLabelTemplate\"\n [context]=\"field\"\n [additionalContext]=\"{label: label}\"></ng-container>\n }\n</ng-template>\n@if (field.display) {\n @if (props.labelAlign === \"before\") {\n <ng-container [ngTemplateOutlet]=\"labelTemplate\"></ng-container>\n }\n <tabs class=\"field-container\" [testId]=\"(field.testId || 'form') + '-tab'\">\n @for (itemField of field.fieldGroup; track itemField) {\n @if (itemField.display) {\n @if (props.useTabs && itemField.wrappers | includes: 'form-fieldset') {\n <div class=\"form-fieldset-item\"\n [tabsItem]=\"itemField.id\"\n [classes]=\"['form-fieldset-tab', itemField.valid === false ? 'invalid' : 'valid']\"\n [label]=\"itemField.props.label\">\n <formly-field [field]=\"itemField\"></formly-field>\n </div>\n } @else {\n <formly-field [field]=\"itemField\"></formly-field>\n }\n }\n }\n @if (showError && field.key !== null) {\n <div *ngIf=\"showError\" class=\"field-errors invalid-feedback\">\n <formly-validation-message\n [field]=\"field\"\n id=\"{{ id }}-formly-validation-error\"\n role=\"alert\"\n ></formly-validation-message>\n </div>\n }\n </tabs>\n @if (props.labelAlign === \"after\") {\n <ng-container [ngTemplateOutlet]=\"labelTemplate\"></ng-container>\n }\n}\n", styles: [".form-fieldset-item.hidden-tab{display:none}.form-fieldset-tab{position:relative;--invalid-bg: rgba(184, 38, 38, 1);--invalid-border: rgba(184, 38, 38, .6);--invalid-color: #ececec;--invalid-box-size: 15px;--invalid-box-pull: -3px}.form-fieldset-tab.invalid>btn .async-target{border:1px solid var(--invalid-border)}.form-fieldset-tab.invalid:after{background:var(--invalid-bg);color:var(--invalid-color);font-size:10px;line-height:var(--invalid-box-size);width:var(--invalid-box-size);height:var(--invalid-box-size);text-align:center;border-radius:5px;content:\"!\";display:block;position:absolute;top:var(--invalid-box-pull);right:var(--invalid-box-pull)}\n"] }]
|
|
2262
2282
|
}] });
|
|
2263
2283
|
|
|
2264
2284
|
// --- Components ---
|