@olafvv/ngx-dynamic-form 0.0.2 → 0.1.0
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/esm2022/lib/components/dynamic-form/dynamic-form.component.mjs +21 -15
- package/esm2022/lib/components/dynamic-form-field/dynamic-form-field.component.mjs +17 -3
- package/esm2022/lib/controls/button/dynamic-button.component.mjs +3 -3
- package/esm2022/lib/controls/button-toggles/dynamic-button-toggles.component.mjs +27 -0
- package/esm2022/lib/controls/button-toggles/dynamic-button-toggles.model.mjs +11 -0
- package/esm2022/lib/controls/checkbox/dynamic-checkbox.component.mjs +5 -11
- package/esm2022/lib/controls/index.mjs +2 -1
- package/esm2022/lib/controls/input/dynamic-input.component.mjs +12 -11
- package/esm2022/lib/controls/input/dynamic-input.model.mjs +2 -1
- package/esm2022/lib/controls/readonly/dynamic-readonly.component.mjs +3 -3
- package/esm2022/lib/controls/select/dynamic-select.component.mjs +5 -11
- package/esm2022/lib/controls/textarea/dynamic-textarea.component.mjs +12 -11
- package/esm2022/lib/models/classes/dynamic-form-field-base.mjs +28 -0
- package/esm2022/lib/models/classes/dynamic-form-field-model.mjs +1 -1
- package/esm2022/lib/models/constants/dynamic-relations.const.mjs +2 -15
- package/esm2022/lib/models/index.mjs +4 -3
- package/esm2022/lib/models/interfaces/dynamic-form-field-config.interface.mjs +1 -1
- package/esm2022/lib/models/interfaces/dynamic-form-field-event.interface.mjs +2 -0
- package/esm2022/lib/models/interfaces/dynamic-form-field-relation.interface.mjs +15 -0
- package/esm2022/lib/services/dynamic-form-relations.service.mjs +3 -2
- package/esm2022/lib/services/dynamic-form.service.mjs +12 -8
- package/fesm2022/olafvv-ngx-dynamic-form.mjs +186 -146
- package/fesm2022/olafvv-ngx-dynamic-form.mjs.map +1 -1
- package/lib/components/dynamic-form/dynamic-form.component.d.ts +15 -9
- package/lib/components/dynamic-form-field/dynamic-form-field.component.d.ts +6 -2
- package/lib/controls/button/dynamic-button.component.d.ts +2 -2
- package/lib/controls/button-toggles/dynamic-button-toggles.component.d.ts +13 -0
- package/lib/controls/button-toggles/dynamic-button-toggles.model.d.ts +12 -0
- package/lib/controls/checkbox/dynamic-checkbox.component.d.ts +3 -5
- package/lib/controls/index.d.ts +1 -0
- package/lib/controls/input/dynamic-input.component.d.ts +6 -6
- package/lib/controls/input/dynamic-input.model.d.ts +2 -0
- package/lib/controls/readonly/dynamic-readonly.component.d.ts +2 -2
- package/lib/controls/select/dynamic-select.component.d.ts +5 -6
- package/lib/controls/textarea/dynamic-textarea.component.d.ts +6 -6
- package/lib/models/classes/{dynamic-form-field-base-component.d.ts → dynamic-form-field-base.d.ts} +2 -8
- package/lib/models/classes/dynamic-form-field-model.d.ts +2 -3
- package/lib/models/constants/dynamic-relations.const.d.ts +1 -29
- package/lib/models/index.d.ts +3 -2
- package/lib/models/interfaces/dynamic-form-field-config.interface.d.ts +4 -5
- package/lib/models/interfaces/dynamic-form-field-event.interface.d.ts +10 -0
- package/lib/models/interfaces/dynamic-form-field-relation.interface.d.ts +29 -0
- package/lib/services/dynamic-form.service.d.ts +12 -8
- package/package.json +1 -1
- package/esm2022/lib/models/classes/dynamic-form-field-base-component.mjs +0 -34
- package/esm2022/lib/models/types/dynamic-form-hook.type.mjs +0 -2
- package/lib/models/types/dynamic-form-hook.type.d.ts +0 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NgFor, AsyncPipe, NgIf, NgClass } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { InjectionToken, Injectable, Inject, Optional, Component, Input,
|
|
3
|
+
import { InjectionToken, Injectable, Inject, Optional, EventEmitter, Component, Input, Output, ViewChild, inject, Injector, ViewContainerRef, ChangeDetectionStrategy } from '@angular/core';
|
|
4
4
|
import * as i1 from '@angular/forms';
|
|
5
5
|
import { UntypedFormControl, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
6
6
|
import { map, BehaviorSubject, of, isObservable, startWith, distinctUntilChanged, Subscription } from 'rxjs';
|
|
7
|
-
import * as i1$1 from '@angular/material/button';
|
|
7
|
+
import * as i1$1 from '@angular/material/button-toggle';
|
|
8
|
+
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
9
|
+
import * as i1$2 from '@angular/material/button';
|
|
8
10
|
import { MatButtonModule } from '@angular/material/button';
|
|
9
11
|
import * as i2 from '@angular/material/checkbox';
|
|
10
12
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
11
|
-
import * as i1$
|
|
13
|
+
import * as i1$3 from '@angular/material/form-field';
|
|
12
14
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
13
15
|
import * as i5 from '@angular/material/icon';
|
|
14
16
|
import { MatIconModule } from '@angular/material/icon';
|
|
@@ -74,8 +76,8 @@ class DynamicFormService {
|
|
|
74
76
|
/**
|
|
75
77
|
* Create a FormGroup from the provided form configuration.
|
|
76
78
|
* Returns a FormGroup.
|
|
77
|
-
* @param config
|
|
78
|
-
* @returns
|
|
79
|
+
* @param {DynamicFormConfig} config Configuration object of a form
|
|
80
|
+
* @returns {UntypedFormGroup}
|
|
79
81
|
*/
|
|
80
82
|
createFormGroup(config) {
|
|
81
83
|
const group = this.fb.group({});
|
|
@@ -94,12 +96,16 @@ class DynamicFormService {
|
|
|
94
96
|
}
|
|
95
97
|
/**
|
|
96
98
|
* Transform any list (Observable) to a list of DynamicFormFieldOption which is used in any Dynamic Form Field with options (e.g. DynamicSelect).
|
|
99
|
+
* Possible to provide the method with Type definitions to define the provided list type and desired option value type:
|
|
100
|
+
*
|
|
101
|
+
* `dynamicFormService.toDynamicOptionList<T, K>(...)`
|
|
102
|
+
*
|
|
97
103
|
* Generic types:
|
|
98
|
-
* T = The type of the items in the provided list
|
|
99
|
-
* K = The type of the value inside an DynamicFormFieldOption
|
|
100
|
-
* @param listObs
|
|
101
|
-
* @param labelCb
|
|
102
|
-
* @param valueCb
|
|
104
|
+
* - T = The type of the items in the provided list
|
|
105
|
+
* - K = The type of the value inside an DynamicFormFieldOption. Default is 'string'
|
|
106
|
+
* @param listObs An Observable of a list of items of type T
|
|
107
|
+
* @param labelCb Callback to define the label of the options in the template
|
|
108
|
+
* @param valueCb Callback to define the value of the options. Must return a value of type K (default string)
|
|
103
109
|
* @returns
|
|
104
110
|
*/
|
|
105
111
|
toDynamicOptionListObs(listObs, labelCb, valueCb) {
|
|
@@ -127,7 +133,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
127
133
|
type: Optional
|
|
128
134
|
}] }, { type: i1.FormBuilder }, { type: DynamicFormValidationsService }]; } });
|
|
129
135
|
|
|
130
|
-
class
|
|
136
|
+
class DynamicFormFieldBase {
|
|
131
137
|
get id() {
|
|
132
138
|
return this.model.id ?? this.model.name;
|
|
133
139
|
}
|
|
@@ -144,14 +150,8 @@ class DynamicFormFieldBaseComponent {
|
|
|
144
150
|
get isInvalid() {
|
|
145
151
|
return this.control.invalid;
|
|
146
152
|
}
|
|
147
|
-
|
|
148
|
-
this.
|
|
149
|
-
}
|
|
150
|
-
onChange(ev) {
|
|
151
|
-
this.change.emit(ev);
|
|
152
|
-
}
|
|
153
|
-
onFocus(ev) {
|
|
154
|
-
this.focus.emit(ev);
|
|
153
|
+
onChange(event) {
|
|
154
|
+
this.change.emit(event);
|
|
155
155
|
}
|
|
156
156
|
resetControl() {
|
|
157
157
|
this.group.get(this.model.name)?.reset();
|
|
@@ -161,20 +161,23 @@ class DynamicFormFieldBaseComponent {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
class
|
|
165
|
-
|
|
166
|
-
|
|
164
|
+
class DynamicButtonTogglesComponent extends DynamicFormFieldBase {
|
|
165
|
+
constructor() {
|
|
166
|
+
super(...arguments);
|
|
167
|
+
this.change = new EventEmitter();
|
|
167
168
|
}
|
|
168
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type:
|
|
169
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type:
|
|
169
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicButtonTogglesComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
170
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicButtonTogglesComponent, isStandalone: true, selector: "app-dynamic-button-toggles", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<ng-container [formGroup]=\"group\">\n <mat-button-toggle-group [id]=\"id\"\n [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n [vertical]=\"model.vertical\"\n (change)=\"onChange($event)\">\n <mat-button-toggle *ngFor=\"let option of model.options$ | async\"\n [value]=\"option.value\">{{option.label}}</mat-button-toggle>\n </mat-button-toggle-group>\n</ng-container>", dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i1$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
170
171
|
}
|
|
171
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type:
|
|
172
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicButtonTogglesComponent, decorators: [{
|
|
172
173
|
type: Component,
|
|
173
|
-
args: [{ standalone: true, imports: [
|
|
174
|
+
args: [{ standalone: true, imports: [NgFor, MatButtonToggleModule, ReactiveFormsModule, AsyncPipe], selector: 'app-dynamic-button-toggles', template: "<ng-container [formGroup]=\"group\">\n <mat-button-toggle-group [id]=\"id\"\n [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n [vertical]=\"model.vertical\"\n (change)=\"onChange($event)\">\n <mat-button-toggle *ngFor=\"let option of model.options$ | async\"\n [value]=\"option.value\">{{option.label}}</mat-button-toggle>\n </mat-button-toggle-group>\n</ng-container>" }]
|
|
174
175
|
}], propDecorators: { model: [{
|
|
175
176
|
type: Input
|
|
176
177
|
}], group: [{
|
|
177
178
|
type: Input
|
|
179
|
+
}], change: [{
|
|
180
|
+
type: Output
|
|
178
181
|
}] } });
|
|
179
182
|
|
|
180
183
|
class DynamicFormFieldModel {
|
|
@@ -200,6 +203,100 @@ class DynamicFormFieldModel {
|
|
|
200
203
|
}
|
|
201
204
|
}
|
|
202
205
|
|
|
206
|
+
class DynamicFormFieldValueModel extends DynamicFormFieldModel {
|
|
207
|
+
constructor(config) {
|
|
208
|
+
super(config);
|
|
209
|
+
this._defaultValue = config.defaultValue ?? null;
|
|
210
|
+
this._value = config.value ?? null;
|
|
211
|
+
this._value$ = new BehaviorSubject(this._value);
|
|
212
|
+
this.valueChanges = this._value$.asObservable();
|
|
213
|
+
}
|
|
214
|
+
get defaultValue() {
|
|
215
|
+
return this._defaultValue;
|
|
216
|
+
}
|
|
217
|
+
set defaultValue(val) {
|
|
218
|
+
this._defaultValue = val;
|
|
219
|
+
}
|
|
220
|
+
get value() {
|
|
221
|
+
return this._value$.getValue();
|
|
222
|
+
}
|
|
223
|
+
set value(val) {
|
|
224
|
+
this._value$.next(val);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Base class for any DynamicFormField with options (e.g. DynamicSelect or DynamicAutocomplete)
|
|
230
|
+
*/
|
|
231
|
+
class DynamicFormFieldOptionModel extends DynamicFormFieldValueModel {
|
|
232
|
+
constructor(config) {
|
|
233
|
+
super(config);
|
|
234
|
+
this._options = [];
|
|
235
|
+
this._groupedOptions = [];
|
|
236
|
+
if (!config.options && !config.groupedOptions) {
|
|
237
|
+
console.error(`No options or groupedOptions provided for ${this.name}`);
|
|
238
|
+
}
|
|
239
|
+
if (config.options) {
|
|
240
|
+
this.options$ = this.setOptions(config.options);
|
|
241
|
+
}
|
|
242
|
+
else if (config.groupedOptions) {
|
|
243
|
+
this.groupedOptions$ = this.setGroupedOptions(config.groupedOptions);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
setOptions(options) {
|
|
247
|
+
if (Array.isArray(options)) {
|
|
248
|
+
this._options = options;
|
|
249
|
+
return of(this._options);
|
|
250
|
+
}
|
|
251
|
+
if (isObservable(options)) {
|
|
252
|
+
return options.pipe(map((o) => {
|
|
253
|
+
this._options = o;
|
|
254
|
+
return this._options;
|
|
255
|
+
}));
|
|
256
|
+
}
|
|
257
|
+
return of([]);
|
|
258
|
+
}
|
|
259
|
+
setGroupedOptions(groupedOptions) {
|
|
260
|
+
if (Array.isArray(groupedOptions)) {
|
|
261
|
+
this._groupedOptions = groupedOptions;
|
|
262
|
+
return of(this._groupedOptions);
|
|
263
|
+
}
|
|
264
|
+
if (isObservable(groupedOptions)) {
|
|
265
|
+
return groupedOptions.pipe(map((o) => {
|
|
266
|
+
this._groupedOptions = o;
|
|
267
|
+
return this._groupedOptions;
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
return of([]);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const DYNAMIC_FORM_FIELD_BUTTON_TOGGLES = 'button-toggles';
|
|
275
|
+
class DynamicButtonToggles extends DynamicFormFieldOptionModel {
|
|
276
|
+
constructor(config) {
|
|
277
|
+
super(config);
|
|
278
|
+
this.type = DYNAMIC_FORM_FIELD_BUTTON_TOGGLES;
|
|
279
|
+
this.multiple = config.multiple ?? false;
|
|
280
|
+
this.vertical = config.vertical ?? false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
class DynamicButtonComponent extends DynamicFormFieldBase {
|
|
285
|
+
onClick() {
|
|
286
|
+
this.model.onClick();
|
|
287
|
+
}
|
|
288
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
289
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicButtonComponent, isStandalone: true, selector: "dynamic-button", inputs: { model: "model", group: "group" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"model.raised else stroked\">\n <button mat-raised-button\n color=\"primary\"\n [id]=\"id\"\n (click)=\"onClick()\">\n <span>{{model.text}}</span>\n </button>\n</ng-container>\n\n<ng-template #stroked>\n <button mat-stroked-button\n color=\"primary\"\n [id]=\"id\"\n (click)=\"onClick()\">\n <span>{{model.text}}</span>\n </button>\n</ng-template>", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }] }); }
|
|
290
|
+
}
|
|
291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicButtonComponent, decorators: [{
|
|
292
|
+
type: Component,
|
|
293
|
+
args: [{ standalone: true, imports: [NgIf, MatButtonModule], selector: 'dynamic-button', template: "<ng-container *ngIf=\"model.raised else stroked\">\n <button mat-raised-button\n color=\"primary\"\n [id]=\"id\"\n (click)=\"onClick()\">\n <span>{{model.text}}</span>\n </button>\n</ng-container>\n\n<ng-template #stroked>\n <button mat-stroked-button\n color=\"primary\"\n [id]=\"id\"\n (click)=\"onClick()\">\n <span>{{model.text}}</span>\n </button>\n</ng-template>" }]
|
|
294
|
+
}], propDecorators: { model: [{
|
|
295
|
+
type: Input
|
|
296
|
+
}], group: [{
|
|
297
|
+
type: Input
|
|
298
|
+
}] } });
|
|
299
|
+
|
|
203
300
|
const DYNAMIC_FORM_FIELD_BUTTON = 'button';
|
|
204
301
|
class DynamicButton extends DynamicFormFieldModel {
|
|
205
302
|
constructor(config) {
|
|
@@ -211,53 +308,25 @@ class DynamicButton extends DynamicFormFieldModel {
|
|
|
211
308
|
}
|
|
212
309
|
}
|
|
213
310
|
|
|
214
|
-
class DynamicCheckboxComponent extends
|
|
311
|
+
class DynamicCheckboxComponent extends DynamicFormFieldBase {
|
|
215
312
|
constructor() {
|
|
216
313
|
super(...arguments);
|
|
217
|
-
this.blur = new EventEmitter();
|
|
218
314
|
this.change = new EventEmitter();
|
|
219
|
-
this.focus = new EventEmitter();
|
|
220
315
|
}
|
|
221
316
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicCheckboxComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
222
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicCheckboxComponent, isStandalone: true, selector: "dynamic-checkbox", inputs: { model: "model", group: "group" }, outputs: {
|
|
317
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicCheckboxComponent, isStandalone: true, selector: "dynamic-checkbox", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<ng-container [formGroup]=\"group\">\n <mat-checkbox [checked]=\"model.checked\"\n [formControlName]=\"model.name\"\n [indeterminate]=\"model.indeterminate\"\n [labelPosition]=\"model.labelPosition\"\n [name]=\"model.name\"\n [id]=\"id\"\n (change)=\"onChange($event)\">\n\n <span class=\"checkbox-label\">{{model.label}}</span>\n </mat-checkbox>\n</ng-container>", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }] }); }
|
|
223
318
|
}
|
|
224
319
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicCheckboxComponent, decorators: [{
|
|
225
320
|
type: Component,
|
|
226
|
-
args: [{ selector: 'dynamic-checkbox', standalone: true, imports: [ReactiveFormsModule, MatCheckboxModule], template: "<ng-container [formGroup]=\"group\">\n <mat-checkbox [checked]=\"model.checked\"\n [formControlName]=\"model.name\"\n [indeterminate]=\"model.indeterminate\"\n [labelPosition]=\"model.labelPosition\"\n [name]=\"model.name\"\n [id]=\"id\"\n (
|
|
321
|
+
args: [{ selector: 'dynamic-checkbox', standalone: true, imports: [ReactiveFormsModule, MatCheckboxModule], template: "<ng-container [formGroup]=\"group\">\n <mat-checkbox [checked]=\"model.checked\"\n [formControlName]=\"model.name\"\n [indeterminate]=\"model.indeterminate\"\n [labelPosition]=\"model.labelPosition\"\n [name]=\"model.name\"\n [id]=\"id\"\n (change)=\"onChange($event)\">\n\n <span class=\"checkbox-label\">{{model.label}}</span>\n </mat-checkbox>\n</ng-container>" }]
|
|
227
322
|
}], propDecorators: { model: [{
|
|
228
323
|
type: Input
|
|
229
324
|
}], group: [{
|
|
230
325
|
type: Input
|
|
231
|
-
}], blur: [{
|
|
232
|
-
type: Output
|
|
233
326
|
}], change: [{
|
|
234
327
|
type: Output
|
|
235
|
-
}], focus: [{
|
|
236
|
-
type: Output
|
|
237
328
|
}] } });
|
|
238
329
|
|
|
239
|
-
class DynamicFormFieldValueModel extends DynamicFormFieldModel {
|
|
240
|
-
constructor(config) {
|
|
241
|
-
super(config);
|
|
242
|
-
this._defaultValue = config.defaultValue ?? null;
|
|
243
|
-
this._value = config.value ?? null;
|
|
244
|
-
this._value$ = new BehaviorSubject(this._value);
|
|
245
|
-
this.valueChanges = this._value$.asObservable();
|
|
246
|
-
}
|
|
247
|
-
get defaultValue() {
|
|
248
|
-
return this._defaultValue;
|
|
249
|
-
}
|
|
250
|
-
set defaultValue(val) {
|
|
251
|
-
this._defaultValue = val;
|
|
252
|
-
}
|
|
253
|
-
get value() {
|
|
254
|
-
return this._value$.getValue();
|
|
255
|
-
}
|
|
256
|
-
set value(val) {
|
|
257
|
-
this._value$.next(val);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
330
|
const DYNAMIC_FORM_FIELD_CHECKBOX = 'checkbox';
|
|
262
331
|
class DynamicCheckbox extends DynamicFormFieldValueModel {
|
|
263
332
|
constructor(config) {
|
|
@@ -278,12 +347,10 @@ class DynamicCheckbox extends DynamicFormFieldValueModel {
|
|
|
278
347
|
}
|
|
279
348
|
}
|
|
280
349
|
|
|
281
|
-
class DynamicInputComponent extends
|
|
350
|
+
class DynamicInputComponent extends DynamicFormFieldBase {
|
|
282
351
|
constructor() {
|
|
283
352
|
super(...arguments);
|
|
284
|
-
this.blur = new EventEmitter();
|
|
285
353
|
this.change = new EventEmitter();
|
|
286
|
-
this.focus = new EventEmitter();
|
|
287
354
|
}
|
|
288
355
|
get valueCount() {
|
|
289
356
|
return this.input?.value ? this.input.value.length : 0;
|
|
@@ -294,12 +361,19 @@ class DynamicInputComponent extends DynamicFormFieldBaseComponent {
|
|
|
294
361
|
get showClear() {
|
|
295
362
|
return !!this.control.value && !this.control.disabled;
|
|
296
363
|
}
|
|
364
|
+
onChange(event) {
|
|
365
|
+
// Ignore the native HTML 5 change event
|
|
366
|
+
if (event instanceof Event) {
|
|
367
|
+
event.stopPropagation();
|
|
368
|
+
}
|
|
369
|
+
this.change.emit(event);
|
|
370
|
+
}
|
|
297
371
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
298
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicInputComponent, isStandalone: true, selector: "dynamic-input", inputs: { model: "model", group: "group" }, outputs: {
|
|
372
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicInputComponent, isStandalone: true, selector: "dynamic-input", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, viewQueries: [{ propertyName: "input", first: true, predicate: MatInput, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label *ngIf=\"model.label\">{{model.label}}</mat-label>\n\n <span matTextPrefix\n *ngIf=\"model.prefix\">{{model.prefix}}</span>\n\n <input matInput\n [type]=\"model.inputType\"\n [formControlName]=\"model.name\"\n [attr.min]=\"model.min\"\n [attr.max]=\"model.max\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [pattern]=\"model.pattern\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\" />\n\n <button matSuffix\n mat-icon-button\n *ngIf=\"showClear\"\n (click)=\"resetControl()\">\n <mat-icon fontIcon=\"clear\"></mat-icon>\n </button>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <mat-hint *ngIf=\"model.maxLength\"\n align=\"end\">{{maxCountText}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i1$3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i1$3.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i1$3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
|
|
299
373
|
}
|
|
300
374
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicInputComponent, decorators: [{
|
|
301
375
|
type: Component,
|
|
302
|
-
args: [{ selector: 'dynamic-input', standalone: true, imports: [NgIf, NgFor, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule, MatIconModule], template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label *ngIf=\"model.label\">{{model.label}}</mat-label>\n\n <span matTextPrefix\n *ngIf=\"model.prefix\">{{model.prefix}}</span>\n\n <input matInput\n [type]=\"model.inputType\"\n [formControlName]=\"model.name\"\n [attr.min]=\"model.min\"\n [attr.max]=\"model.max\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [pattern]=\"model.pattern\"\n [autocomplete]=\"model.autocomplete\" />\n\n <button matSuffix\n mat-icon-button\n *ngIf=\"showClear\"\n (click)=\"resetControl()\">\n <mat-icon fontIcon=\"clear\"></mat-icon>\n </button>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <mat-hint *ngIf=\"model.maxLength\"\n align=\"end\">{{maxCountText}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
376
|
+
args: [{ selector: 'dynamic-input', standalone: true, imports: [NgIf, NgFor, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatButtonModule, MatIconModule], template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label *ngIf=\"model.label\">{{model.label}}</mat-label>\n\n <span matTextPrefix\n *ngIf=\"model.prefix\">{{model.prefix}}</span>\n\n <input matInput\n [type]=\"model.inputType\"\n [formControlName]=\"model.name\"\n [attr.min]=\"model.min\"\n [attr.max]=\"model.max\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [pattern]=\"model.pattern\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\" />\n\n <button matSuffix\n mat-icon-button\n *ngIf=\"showClear\"\n (click)=\"resetControl()\">\n <mat-icon fontIcon=\"clear\"></mat-icon>\n </button>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <mat-hint *ngIf=\"model.maxLength\"\n align=\"end\">{{maxCountText}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
303
377
|
}], propDecorators: { input: [{
|
|
304
378
|
type: ViewChild,
|
|
305
379
|
args: [MatInput, { static: true }]
|
|
@@ -307,12 +381,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
307
381
|
type: Input
|
|
308
382
|
}], group: [{
|
|
309
383
|
type: Input
|
|
310
|
-
}], blur: [{
|
|
311
|
-
type: Output
|
|
312
384
|
}], change: [{
|
|
313
385
|
type: Output
|
|
314
|
-
}], focus: [{
|
|
315
|
-
type: Output
|
|
316
386
|
}] } });
|
|
317
387
|
|
|
318
388
|
const DYNAMIC_FORM_FIELD_INPUT = 'input';
|
|
@@ -329,10 +399,11 @@ class DynamicInput extends DynamicFormFieldValueModel {
|
|
|
329
399
|
this.pattern = config.pattern ?? '';
|
|
330
400
|
this.autocomplete = config.autocomplete ?? 'off';
|
|
331
401
|
this.prefix = config.prefix ?? null;
|
|
402
|
+
this.hideClearIcon = config.hideClearIcon ?? false;
|
|
332
403
|
}
|
|
333
404
|
}
|
|
334
405
|
|
|
335
|
-
class DynamicReadonlyComponent extends
|
|
406
|
+
class DynamicReadonlyComponent extends DynamicFormFieldBase {
|
|
336
407
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicReadonlyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
337
408
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicReadonlyComponent, isStandalone: true, selector: "dynamic-readonly", inputs: { model: "model", group: "group" }, usesInheritance: true, ngImport: i0, template: "<div class=\"dynamic-form-field-readonly\"\n [formGroup]=\"group\"\n [id]=\"id\">\n <div class=\"label\">{{model.label}}</div>\n <span>{{model.value}}</span>\n</div>", styles: [".dynamic-form-field-readonly{width:100%;margin:8px 0;color:var(--mdc-theme-text-primary-on-background, rgba(0, 0, 0, .87))}.dynamic-form-field-readonly .label{font-size:var(--mdc-typography-body2-font-size, 14px);line-height:var(--mdc-typography-body2-line-height, 20px);margin-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }] }); }
|
|
338
409
|
}
|
|
@@ -353,80 +424,28 @@ class DynamicReadonly extends DynamicFormFieldValueModel {
|
|
|
353
424
|
}
|
|
354
425
|
}
|
|
355
426
|
|
|
356
|
-
class DynamicSelectComponent extends
|
|
427
|
+
class DynamicSelectComponent extends DynamicFormFieldBase {
|
|
357
428
|
constructor() {
|
|
358
429
|
super(...arguments);
|
|
359
|
-
this.blur = new EventEmitter();
|
|
360
430
|
this.change = new EventEmitter();
|
|
361
|
-
this.focus = new EventEmitter();
|
|
362
431
|
}
|
|
363
432
|
trackByFn(index, option) {
|
|
364
433
|
return option.value;
|
|
365
434
|
}
|
|
366
435
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
367
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicSelectComponent, isStandalone: true, selector: "dynamic-select", inputs: { model: "model", group: "group" }, outputs: {
|
|
436
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicSelectComponent, isStandalone: true, selector: "dynamic-select", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label>{{model.label}}</mat-label>\n\n <!-- Template for select without grouped options -->\n <ng-container *ngIf=\"model.options$ | async as options\">\n <ng-container *ngIf=\"!model.native else nativeSelect\">\n <mat-select [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n (selectionChange)=\"onChange($event)\">\n <mat-option *ngFor=\"let option of options; trackBy: trackByFn\"\n [value]=\"option.value\">\n {{option.label}}\n </mat-option>\n </mat-select>\n </ng-container>\n\n <ng-template #nativeSelect>\n <select matNativeControl\n (selectionchange)=\"onChange($event)\">\n <option *ngFor=\"let option of options\"\n [value]=\"option.value\">\n {{option.label}}\n </option>\n </select>\n </ng-template>\n </ng-container>\n\n <!-- Template for select with grouped options -->\n <ng-container *ngIf=\"model.groupedOptions$ | async as groupedOptions\">\n <ng-container *ngIf=\"!model.native else nativeSelectGrouped\">\n <mat-select [formControlName]=\"model.name\"\n (selectionChange)=\"onChange($event)\">\n <mat-optgroup *ngFor=\"let group of groupedOptions\"\n [label]=\"group.name\">\n <mat-option *ngFor=\"let option of group.options; trackBy: trackByFn\"\n [value]=\"option.value\">\n {{option.label}}\n </mat-option>\n </mat-optgroup>\n </mat-select>\n </ng-container>\n\n <ng-template #nativeSelectGrouped>\n <select matNativeControl\n (selectionchange)=\"onChange($event)\">\n <optgroup *ngFor=\"let group of groupedOptions\"\n [label]=\"group.name\">\n <option *ngFor=\"let option of group.options\"\n [value]=\"option.value\">\n {{option.label}}\n </option>\n </optgroup>\n </select>\n </ng-template>\n </ng-container>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}mat-option{padding-top:8px;padding-bottom:8px}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i1$3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i4.MatOptgroup, selector: "mat-optgroup", inputs: ["disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] }); }
|
|
368
437
|
}
|
|
369
438
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicSelectComponent, decorators: [{
|
|
370
439
|
type: Component,
|
|
371
|
-
args: [{ standalone: true, imports: [NgIf, NgFor, MatFormFieldModule, ReactiveFormsModule, MatSelectModule, MatOptionModule, AsyncPipe, MatInputModule], selector: 'dynamic-select', template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label>{{model.label}}</mat-label>\n\n <!-- Template for select without grouped options -->\n <ng-container *ngIf=\"model.options$ | async as options\">\n <ng-container *ngIf=\"!model.native else nativeSelect\">\n <mat-select [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\">\n <mat-option *ngFor=\"let option of options; trackBy: trackByFn\"\n [value]=\"option.value\">\n {{option.label}}\n </mat-option>\n </mat-select>\n </ng-container>\n\n <ng-template #nativeSelect>\n <select matNativeControl>\n <option *ngFor=\"let option of options\"\n [value]=\"option.value\">\n {{option.label}}\n </option>\n </select>\n </ng-template>\n </ng-container>\n\n <!-- Template for select with grouped options -->\n <ng-container *ngIf=\"model.groupedOptions$ | async as groupedOptions\">\n <ng-container *ngIf=\"!model.native else nativeSelectGrouped\">\n <mat-select [formControlName]=\"model.name\">\n <mat-optgroup *ngFor=\"let group of groupedOptions\"\n [label]=\"group.name\">\n <mat-option *ngFor=\"let option of group.options; trackBy: trackByFn\"\n [value]=\"option.value\">\n {{option.label}}\n </mat-option>\n </mat-optgroup>\n </mat-select>\n </ng-container>\n\n <ng-template #nativeSelectGrouped>\n <select matNativeControl>\n <optgroup *ngFor=\"let group of groupedOptions\"\n [label]=\"group.name\">\n <option *ngFor=\"let option of group.options\"\n [value]=\"option.value\">\n {{option.label}}\n </option>\n </optgroup>\n </select>\n </ng-template>\n </ng-container>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}mat-option{padding-top:8px;padding-bottom:8px}\n"] }]
|
|
440
|
+
args: [{ standalone: true, imports: [NgIf, NgFor, MatFormFieldModule, ReactiveFormsModule, MatSelectModule, MatOptionModule, AsyncPipe, MatInputModule], selector: 'dynamic-select', template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label>{{model.label}}</mat-label>\n\n <!-- Template for select without grouped options -->\n <ng-container *ngIf=\"model.options$ | async as options\">\n <ng-container *ngIf=\"!model.native else nativeSelect\">\n <mat-select [formControlName]=\"model.name\"\n [multiple]=\"model.multiple\"\n (selectionChange)=\"onChange($event)\">\n <mat-option *ngFor=\"let option of options; trackBy: trackByFn\"\n [value]=\"option.value\">\n {{option.label}}\n </mat-option>\n </mat-select>\n </ng-container>\n\n <ng-template #nativeSelect>\n <select matNativeControl\n (selectionchange)=\"onChange($event)\">\n <option *ngFor=\"let option of options\"\n [value]=\"option.value\">\n {{option.label}}\n </option>\n </select>\n </ng-template>\n </ng-container>\n\n <!-- Template for select with grouped options -->\n <ng-container *ngIf=\"model.groupedOptions$ | async as groupedOptions\">\n <ng-container *ngIf=\"!model.native else nativeSelectGrouped\">\n <mat-select [formControlName]=\"model.name\"\n (selectionChange)=\"onChange($event)\">\n <mat-optgroup *ngFor=\"let group of groupedOptions\"\n [label]=\"group.name\">\n <mat-option *ngFor=\"let option of group.options; trackBy: trackByFn\"\n [value]=\"option.value\">\n {{option.label}}\n </mat-option>\n </mat-optgroup>\n </mat-select>\n </ng-container>\n\n <ng-template #nativeSelectGrouped>\n <select matNativeControl\n (selectionchange)=\"onChange($event)\">\n <optgroup *ngFor=\"let group of groupedOptions\"\n [label]=\"group.name\">\n <option *ngFor=\"let option of group.options\"\n [value]=\"option.value\">\n {{option.label}}\n </option>\n </optgroup>\n </select>\n </ng-template>\n </ng-container>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}mat-option{padding-top:8px;padding-bottom:8px}\n"] }]
|
|
372
441
|
}], propDecorators: { model: [{
|
|
373
442
|
type: Input
|
|
374
443
|
}], group: [{
|
|
375
444
|
type: Input
|
|
376
|
-
}], blur: [{
|
|
377
|
-
type: Output
|
|
378
445
|
}], change: [{
|
|
379
446
|
type: Output
|
|
380
|
-
}], focus: [{
|
|
381
|
-
type: Output
|
|
382
447
|
}] } });
|
|
383
448
|
|
|
384
|
-
/**
|
|
385
|
-
* Base class for any DynamicFormField with options (e.g. DynamicSelect or DynamicAutocomplete)
|
|
386
|
-
*/
|
|
387
|
-
class DynamicFormFieldOptionModel extends DynamicFormFieldValueModel {
|
|
388
|
-
constructor(config) {
|
|
389
|
-
super(config);
|
|
390
|
-
this._options = [];
|
|
391
|
-
this._groupedOptions = [];
|
|
392
|
-
if (!config.options && !config.groupedOptions) {
|
|
393
|
-
console.error(`No options or groupedOptions provided for ${this.name}`);
|
|
394
|
-
}
|
|
395
|
-
if (config.options) {
|
|
396
|
-
this.options$ = this.setOptions(config.options);
|
|
397
|
-
}
|
|
398
|
-
else if (config.groupedOptions) {
|
|
399
|
-
this.groupedOptions$ = this.setGroupedOptions(config.groupedOptions);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
setOptions(options) {
|
|
403
|
-
if (Array.isArray(options)) {
|
|
404
|
-
this._options = options;
|
|
405
|
-
return of(this._options);
|
|
406
|
-
}
|
|
407
|
-
if (isObservable(options)) {
|
|
408
|
-
return options.pipe(map((o) => {
|
|
409
|
-
this._options = o;
|
|
410
|
-
return this._options;
|
|
411
|
-
}));
|
|
412
|
-
}
|
|
413
|
-
return of([]);
|
|
414
|
-
}
|
|
415
|
-
setGroupedOptions(groupedOptions) {
|
|
416
|
-
if (Array.isArray(groupedOptions)) {
|
|
417
|
-
this._groupedOptions = groupedOptions;
|
|
418
|
-
return of(this._groupedOptions);
|
|
419
|
-
}
|
|
420
|
-
if (isObservable(groupedOptions)) {
|
|
421
|
-
return groupedOptions.pipe(map((o) => {
|
|
422
|
-
this._groupedOptions = o;
|
|
423
|
-
return this._groupedOptions;
|
|
424
|
-
}));
|
|
425
|
-
}
|
|
426
|
-
return of([]);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
449
|
const DYNAMIC_FORM_FIELD_SELECT = 'select';
|
|
431
450
|
class DynamicSelect extends DynamicFormFieldOptionModel {
|
|
432
451
|
constructor(config) {
|
|
@@ -437,12 +456,10 @@ class DynamicSelect extends DynamicFormFieldOptionModel {
|
|
|
437
456
|
}
|
|
438
457
|
}
|
|
439
458
|
|
|
440
|
-
class DynamicTextareaComponent extends
|
|
459
|
+
class DynamicTextareaComponent extends DynamicFormFieldBase {
|
|
441
460
|
constructor() {
|
|
442
461
|
super(...arguments);
|
|
443
|
-
this.blur = new EventEmitter();
|
|
444
462
|
this.change = new EventEmitter();
|
|
445
|
-
this.focus = new EventEmitter();
|
|
446
463
|
}
|
|
447
464
|
get valueCount() {
|
|
448
465
|
return this.textarea?.value ? this.textarea.value.length : 0;
|
|
@@ -450,12 +467,19 @@ class DynamicTextareaComponent extends DynamicFormFieldBaseComponent {
|
|
|
450
467
|
get maxCountText() {
|
|
451
468
|
return `${this.valueCount} / ${this.model.maxLength}`;
|
|
452
469
|
}
|
|
470
|
+
onChange(event) {
|
|
471
|
+
// Ignore the native HTML 5 change event
|
|
472
|
+
if (event instanceof Event) {
|
|
473
|
+
event.stopPropagation();
|
|
474
|
+
}
|
|
475
|
+
this.change.emit(event);
|
|
476
|
+
}
|
|
453
477
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
454
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicTextareaComponent, isStandalone: true, selector: "dynamic-textarea", inputs: { model: "model", group: "group" }, outputs: {
|
|
478
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicTextareaComponent, isStandalone: true, selector: "dynamic-textarea", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, viewQueries: [{ propertyName: "textarea", first: true, predicate: MatInput, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label *ngIf=\"model.label\">{{model.label}}</mat-label>\n\n <textarea matInput\n [cdkTextareaAutosize]=\"model.resize\"\n [cdkAutosizeMinRows]=\"model.rows\"\n [cdkAutosizeMaxRows]=\"model.resizeMaxRows\"\n [id]=\"id\"\n [formControlName]=\"model.name\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [rows]=\"model.rows\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\">\n </textarea>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <mat-hint *ngIf=\"model.maxLength\"\n align=\"end\">{{maxCountText}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i1$3.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i3$2.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
|
|
455
479
|
}
|
|
456
480
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicTextareaComponent, decorators: [{
|
|
457
481
|
type: Component,
|
|
458
|
-
args: [{ standalone: true, imports: [NgIf, NgFor, MatFormFieldModule, MatInputModule, ReactiveFormsModule], selector: 'dynamic-textarea', template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label *ngIf=\"model.label\">{{model.label}}</mat-label>\n\n <textarea matInput\n [cdkTextareaAutosize]=\"model.resize\"\n [cdkAutosizeMinRows]=\"model.rows\"\n [cdkAutosizeMaxRows]=\"model.resizeMaxRows\"\n [id]=\"id\"\n [formControlName]=\"model.name\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [rows]=\"model.rows\"\n [autocomplete]=\"model.autocomplete\">\n </textarea>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <mat-hint *ngIf=\"model.maxLength\"\n align=\"end\">{{maxCountText}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
482
|
+
args: [{ standalone: true, imports: [NgIf, NgFor, MatFormFieldModule, MatInputModule, ReactiveFormsModule], selector: 'dynamic-textarea', template: "<mat-form-field [formGroup]=\"group\"\n [id]=\"id\"\n color=\"primary\">\n <mat-label *ngIf=\"model.label\">{{model.label}}</mat-label>\n\n <textarea matInput\n [cdkTextareaAutosize]=\"model.resize\"\n [cdkAutosizeMinRows]=\"model.rows\"\n [cdkAutosizeMaxRows]=\"model.resizeMaxRows\"\n [id]=\"id\"\n [formControlName]=\"model.name\"\n [attr.minLength]=\"model.minLength\"\n [attr.maxLength]=\"model.maxLength\"\n [rows]=\"model.rows\"\n [autocomplete]=\"model.autocomplete\"\n (change)=\"onChange($event)\">\n </textarea>\n\n <mat-hint *ngIf=\"model.hint\"\n align=\"start\">{{model.hint}}</mat-hint>\n\n <mat-hint *ngIf=\"model.maxLength\"\n align=\"end\">{{maxCountText}}</mat-hint>\n\n <ng-container *ngFor=\"let validator of model.validators\"\n ngProjectAs=\"mat-error\">\n <mat-error *ngIf=\"hasError(validator.name)\">{{validator.message}}</mat-error>\n </ng-container>\n</mat-form-field>", styles: ["mat-form-field{width:100%}\n"] }]
|
|
459
483
|
}], propDecorators: { textarea: [{
|
|
460
484
|
type: ViewChild,
|
|
461
485
|
args: [MatInput, { static: true }]
|
|
@@ -463,12 +487,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
463
487
|
type: Input
|
|
464
488
|
}], group: [{
|
|
465
489
|
type: Input
|
|
466
|
-
}], blur: [{
|
|
467
|
-
type: Output
|
|
468
490
|
}], change: [{
|
|
469
491
|
type: Output
|
|
470
|
-
}], focus: [{
|
|
471
|
-
type: Output
|
|
472
492
|
}] } });
|
|
473
493
|
|
|
474
494
|
const DYNAMIC_FORM_FIELD_TEXTAREA = 'textarea';
|
|
@@ -571,6 +591,7 @@ var RelationOperator;
|
|
|
571
591
|
RelationOperator["AND"] = "AND";
|
|
572
592
|
RelationOperator["OR"] = "OR";
|
|
573
593
|
})(RelationOperator || (RelationOperator = {}));
|
|
594
|
+
|
|
574
595
|
const DISABLE_ACTION = {
|
|
575
596
|
type: RelationActionType.DISABLED,
|
|
576
597
|
reversedType: RelationActionType.ENABLED,
|
|
@@ -703,6 +724,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
703
724
|
|
|
704
725
|
class DynamicFormFieldComponent {
|
|
705
726
|
constructor() {
|
|
727
|
+
this.change = new EventEmitter();
|
|
706
728
|
this._subs = new Subscription();
|
|
707
729
|
this.dynamicFormService = inject(DynamicFormService);
|
|
708
730
|
this.relationService = inject(DynamicFormRelationsService);
|
|
@@ -739,6 +761,8 @@ class DynamicFormFieldComponent {
|
|
|
739
761
|
return DynamicSelectComponent;
|
|
740
762
|
case DYNAMIC_FORM_FIELD_BUTTON:
|
|
741
763
|
return DynamicButtonComponent;
|
|
764
|
+
case DYNAMIC_FORM_FIELD_BUTTON_TOGGLES:
|
|
765
|
+
return DynamicButtonTogglesComponent;
|
|
742
766
|
default:
|
|
743
767
|
console.warn(`Model of type 'dynamic-${this.model.type}' is not implemented yet. Add this type to dynamic-form-field.component.ts to add support`);
|
|
744
768
|
return null;
|
|
@@ -749,6 +773,7 @@ class DynamicFormFieldComponent {
|
|
|
749
773
|
if (component != null) {
|
|
750
774
|
let componentRef = this.componentViewContainer.createComponent(component);
|
|
751
775
|
const componentInstance = componentRef.instance;
|
|
776
|
+
this._subs.add(componentInstance.change?.subscribe((event) => this.onChange(event)));
|
|
752
777
|
componentInstance.group = this.group;
|
|
753
778
|
componentInstance.model = this.model;
|
|
754
779
|
}
|
|
@@ -794,8 +819,14 @@ class DynamicFormFieldComponent {
|
|
|
794
819
|
onDisabledChange(disabled) {
|
|
795
820
|
disabled ? this._control.disable() : this._control.enable();
|
|
796
821
|
}
|
|
822
|
+
onChange(ev) {
|
|
823
|
+
this.change.emit(this.createDynamicFormEvent(ev, 'change'));
|
|
824
|
+
}
|
|
825
|
+
createDynamicFormEvent(event, type) {
|
|
826
|
+
return { event, type, control: this._control, form: this.group, model: this.model };
|
|
827
|
+
}
|
|
797
828
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
798
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicFormFieldComponent, isStandalone: true, selector: "dynamic-form-field", inputs: { model: "model", group: "group" }, viewQueries: [{ propertyName: "componentViewContainer", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div [formGroup]=\"group\"\n [ngClass]=\"['dynamic-form-field-container', 'dynamic-form-field-' + model.type]\">\n <ng-container #componentViewContainer></ng-container>\n</div>", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
829
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicFormFieldComponent, isStandalone: true, selector: "dynamic-form-field", inputs: { model: "model", group: "group" }, outputs: { change: "change" }, viewQueries: [{ propertyName: "componentViewContainer", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div [formGroup]=\"group\"\n [ngClass]=\"['dynamic-form-field-container', 'dynamic-form-field-' + model.type]\">\n <ng-container #componentViewContainer></ng-container>\n</div>", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
799
830
|
}
|
|
800
831
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicFormFieldComponent, decorators: [{
|
|
801
832
|
type: Component,
|
|
@@ -807,12 +838,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
807
838
|
type: Input
|
|
808
839
|
}], group: [{
|
|
809
840
|
type: Input
|
|
841
|
+
}], change: [{
|
|
842
|
+
type: Output
|
|
810
843
|
}] } });
|
|
811
844
|
|
|
812
845
|
class DynamicFormComponent {
|
|
813
846
|
constructor() {
|
|
814
|
-
this.
|
|
815
|
-
this.dynamicFormService = inject(DynamicFormService);
|
|
847
|
+
this.change = new EventEmitter();
|
|
816
848
|
}
|
|
817
849
|
/**
|
|
818
850
|
* Get the formConfig as flat array.
|
|
@@ -820,10 +852,12 @@ class DynamicFormComponent {
|
|
|
820
852
|
get flatFormConfig() {
|
|
821
853
|
return this.formConfig.reduce((acc, curr) => acc.concat(curr), []);
|
|
822
854
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
855
|
+
/**
|
|
856
|
+
* TrackBy Function for performance optimization
|
|
857
|
+
* @param _index
|
|
858
|
+
* @param field
|
|
859
|
+
* @returns
|
|
860
|
+
*/
|
|
827
861
|
trackByFn(_index, field) {
|
|
828
862
|
return field.id;
|
|
829
863
|
}
|
|
@@ -839,25 +873,31 @@ class DynamicFormComponent {
|
|
|
839
873
|
* Provides an Observable to listen to changes of a specific field in the form.
|
|
840
874
|
*
|
|
841
875
|
* @param name Name of the field
|
|
842
|
-
* @returns Observable<
|
|
876
|
+
* @returns Observable<unknown>
|
|
843
877
|
*/
|
|
844
|
-
|
|
878
|
+
onControlChange(name) {
|
|
845
879
|
const field = this.group.get(name);
|
|
846
880
|
if (!field) {
|
|
847
881
|
throw new Error(`Cannot find a field with the name ${name} in the FormGroup`);
|
|
848
882
|
}
|
|
849
883
|
return field.valueChanges;
|
|
850
884
|
}
|
|
885
|
+
onChange(event) {
|
|
886
|
+
this.change.emit(event);
|
|
887
|
+
}
|
|
851
888
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
852
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicFormComponent, isStandalone: true, selector: "dynamic-form", inputs: { formConfig: "formConfig" }, outputs: {
|
|
889
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicFormComponent, isStandalone: true, selector: "dynamic-form", inputs: { group: "group", formConfig: "formConfig" }, outputs: { change: "change" }, providers: [DynamicFormService], ngImport: i0, template: "<div *ngFor=\"let row of formConfig\"\n class=\"dynamic-form-row\">\n <dynamic-form-field *ngFor=\"let field of row; trackBy: trackByFn\"\n class=\"dynamic-form-field\"\n [id]=\"field.id\"\n [hidden]=\"field.hidden\"\n [ngClass]=\"[field.type, 'form-field-width-'+field.width]\"\n [group]=\"group\"\n [model]=\"field\"\n (change)=\"onChange($event)\">\n </dynamic-form-field>\n</div>", styles: [".dynamic-form-row{display:flex}.dynamic-form-row .dynamic-form-field{width:100%;margin:4px 0}.dynamic-form-row .dynamic-form-field:not(:last-of-type){margin-right:12px}.dynamic-form-row .dynamic-form-field.button{flex:0}.dynamic-form-row .form-field-width-1{width:1%}.dynamic-form-row .form-field-width-2{width:2%}.dynamic-form-row .form-field-width-3{width:3%}.dynamic-form-row .form-field-width-4{width:4%}.dynamic-form-row .form-field-width-5{width:5%}.dynamic-form-row .form-field-width-6{width:6%}.dynamic-form-row .form-field-width-7{width:7%}.dynamic-form-row .form-field-width-8{width:8%}.dynamic-form-row .form-field-width-9{width:9%}.dynamic-form-row .form-field-width-10{width:10%}.dynamic-form-row .form-field-width-11{width:11%}.dynamic-form-row .form-field-width-12{width:12%}.dynamic-form-row .form-field-width-13{width:13%}.dynamic-form-row .form-field-width-14{width:14%}.dynamic-form-row .form-field-width-15{width:15%}.dynamic-form-row .form-field-width-16{width:16%}.dynamic-form-row .form-field-width-17{width:17%}.dynamic-form-row .form-field-width-18{width:18%}.dynamic-form-row .form-field-width-19{width:19%}.dynamic-form-row .form-field-width-20{width:20%}.dynamic-form-row .form-field-width-21{width:21%}.dynamic-form-row .form-field-width-22{width:22%}.dynamic-form-row .form-field-width-23{width:23%}.dynamic-form-row .form-field-width-24{width:24%}.dynamic-form-row .form-field-width-25{width:25%}.dynamic-form-row .form-field-width-26{width:26%}.dynamic-form-row .form-field-width-27{width:27%}.dynamic-form-row .form-field-width-28{width:28%}.dynamic-form-row .form-field-width-29{width:29%}.dynamic-form-row .form-field-width-30{width:30%}.dynamic-form-row .form-field-width-31{width:31%}.dynamic-form-row .form-field-width-32{width:32%}.dynamic-form-row .form-field-width-33{width:33%}.dynamic-form-row .form-field-width-34{width:34%}.dynamic-form-row .form-field-width-35{width:35%}.dynamic-form-row .form-field-width-36{width:36%}.dynamic-form-row .form-field-width-37{width:37%}.dynamic-form-row .form-field-width-38{width:38%}.dynamic-form-row .form-field-width-39{width:39%}.dynamic-form-row .form-field-width-40{width:40%}.dynamic-form-row .form-field-width-41{width:41%}.dynamic-form-row .form-field-width-42{width:42%}.dynamic-form-row .form-field-width-43{width:43%}.dynamic-form-row .form-field-width-44{width:44%}.dynamic-form-row .form-field-width-45{width:45%}.dynamic-form-row .form-field-width-46{width:46%}.dynamic-form-row .form-field-width-47{width:47%}.dynamic-form-row .form-field-width-48{width:48%}.dynamic-form-row .form-field-width-49{width:49%}.dynamic-form-row .form-field-width-50{width:50%}.dynamic-form-row .form-field-width-51{width:51%}.dynamic-form-row .form-field-width-52{width:52%}.dynamic-form-row .form-field-width-53{width:53%}.dynamic-form-row .form-field-width-54{width:54%}.dynamic-form-row .form-field-width-55{width:55%}.dynamic-form-row .form-field-width-56{width:56%}.dynamic-form-row .form-field-width-57{width:57%}.dynamic-form-row .form-field-width-58{width:58%}.dynamic-form-row .form-field-width-59{width:59%}.dynamic-form-row .form-field-width-60{width:60%}.dynamic-form-row .form-field-width-61{width:61%}.dynamic-form-row .form-field-width-62{width:62%}.dynamic-form-row .form-field-width-63{width:63%}.dynamic-form-row .form-field-width-64{width:64%}.dynamic-form-row .form-field-width-65{width:65%}.dynamic-form-row .form-field-width-66{width:66%}.dynamic-form-row .form-field-width-67{width:67%}.dynamic-form-row .form-field-width-68{width:68%}.dynamic-form-row .form-field-width-69{width:69%}.dynamic-form-row .form-field-width-70{width:70%}.dynamic-form-row .form-field-width-71{width:71%}.dynamic-form-row .form-field-width-72{width:72%}.dynamic-form-row .form-field-width-73{width:73%}.dynamic-form-row .form-field-width-74{width:74%}.dynamic-form-row .form-field-width-75{width:75%}.dynamic-form-row .form-field-width-76{width:76%}.dynamic-form-row .form-field-width-77{width:77%}.dynamic-form-row .form-field-width-78{width:78%}.dynamic-form-row .form-field-width-79{width:79%}.dynamic-form-row .form-field-width-80{width:80%}.dynamic-form-row .form-field-width-81{width:81%}.dynamic-form-row .form-field-width-82{width:82%}.dynamic-form-row .form-field-width-83{width:83%}.dynamic-form-row .form-field-width-84{width:84%}.dynamic-form-row .form-field-width-85{width:85%}.dynamic-form-row .form-field-width-86{width:86%}.dynamic-form-row .form-field-width-87{width:87%}.dynamic-form-row .form-field-width-88{width:88%}.dynamic-form-row .form-field-width-89{width:89%}.dynamic-form-row .form-field-width-90{width:90%}.dynamic-form-row .form-field-width-91{width:91%}.dynamic-form-row .form-field-width-92{width:92%}.dynamic-form-row .form-field-width-93{width:93%}.dynamic-form-row .form-field-width-94{width:94%}.dynamic-form-row .form-field-width-95{width:95%}.dynamic-form-row .form-field-width-96{width:96%}.dynamic-form-row .form-field-width-97{width:97%}.dynamic-form-row .form-field-width-98{width:98%}.dynamic-form-row .form-field-width-99{width:99%}.dynamic-form-row .form-field-width-100{width:100%}\n"], dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: DynamicFormFieldComponent, selector: "dynamic-form-field", inputs: ["model", "group"], outputs: ["change"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
853
890
|
}
|
|
854
891
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicFormComponent, decorators: [{
|
|
855
892
|
type: Component,
|
|
856
|
-
args: [{ standalone: true, imports: [NgFor, NgClass, DynamicFormFieldComponent, ReactiveFormsModule], selector: 'dynamic-form', providers: [DynamicFormService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<
|
|
857
|
-
}], propDecorators: {
|
|
893
|
+
args: [{ standalone: true, imports: [NgFor, NgClass, DynamicFormFieldComponent, ReactiveFormsModule], selector: 'dynamic-form', providers: [DynamicFormService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngFor=\"let row of formConfig\"\n class=\"dynamic-form-row\">\n <dynamic-form-field *ngFor=\"let field of row; trackBy: trackByFn\"\n class=\"dynamic-form-field\"\n [id]=\"field.id\"\n [hidden]=\"field.hidden\"\n [ngClass]=\"[field.type, 'form-field-width-'+field.width]\"\n [group]=\"group\"\n [model]=\"field\"\n (change)=\"onChange($event)\">\n </dynamic-form-field>\n</div>", styles: [".dynamic-form-row{display:flex}.dynamic-form-row .dynamic-form-field{width:100%;margin:4px 0}.dynamic-form-row .dynamic-form-field:not(:last-of-type){margin-right:12px}.dynamic-form-row .dynamic-form-field.button{flex:0}.dynamic-form-row .form-field-width-1{width:1%}.dynamic-form-row .form-field-width-2{width:2%}.dynamic-form-row .form-field-width-3{width:3%}.dynamic-form-row .form-field-width-4{width:4%}.dynamic-form-row .form-field-width-5{width:5%}.dynamic-form-row .form-field-width-6{width:6%}.dynamic-form-row .form-field-width-7{width:7%}.dynamic-form-row .form-field-width-8{width:8%}.dynamic-form-row .form-field-width-9{width:9%}.dynamic-form-row .form-field-width-10{width:10%}.dynamic-form-row .form-field-width-11{width:11%}.dynamic-form-row .form-field-width-12{width:12%}.dynamic-form-row .form-field-width-13{width:13%}.dynamic-form-row .form-field-width-14{width:14%}.dynamic-form-row .form-field-width-15{width:15%}.dynamic-form-row .form-field-width-16{width:16%}.dynamic-form-row .form-field-width-17{width:17%}.dynamic-form-row .form-field-width-18{width:18%}.dynamic-form-row .form-field-width-19{width:19%}.dynamic-form-row .form-field-width-20{width:20%}.dynamic-form-row .form-field-width-21{width:21%}.dynamic-form-row .form-field-width-22{width:22%}.dynamic-form-row .form-field-width-23{width:23%}.dynamic-form-row .form-field-width-24{width:24%}.dynamic-form-row .form-field-width-25{width:25%}.dynamic-form-row .form-field-width-26{width:26%}.dynamic-form-row .form-field-width-27{width:27%}.dynamic-form-row .form-field-width-28{width:28%}.dynamic-form-row .form-field-width-29{width:29%}.dynamic-form-row .form-field-width-30{width:30%}.dynamic-form-row .form-field-width-31{width:31%}.dynamic-form-row .form-field-width-32{width:32%}.dynamic-form-row .form-field-width-33{width:33%}.dynamic-form-row .form-field-width-34{width:34%}.dynamic-form-row .form-field-width-35{width:35%}.dynamic-form-row .form-field-width-36{width:36%}.dynamic-form-row .form-field-width-37{width:37%}.dynamic-form-row .form-field-width-38{width:38%}.dynamic-form-row .form-field-width-39{width:39%}.dynamic-form-row .form-field-width-40{width:40%}.dynamic-form-row .form-field-width-41{width:41%}.dynamic-form-row .form-field-width-42{width:42%}.dynamic-form-row .form-field-width-43{width:43%}.dynamic-form-row .form-field-width-44{width:44%}.dynamic-form-row .form-field-width-45{width:45%}.dynamic-form-row .form-field-width-46{width:46%}.dynamic-form-row .form-field-width-47{width:47%}.dynamic-form-row .form-field-width-48{width:48%}.dynamic-form-row .form-field-width-49{width:49%}.dynamic-form-row .form-field-width-50{width:50%}.dynamic-form-row .form-field-width-51{width:51%}.dynamic-form-row .form-field-width-52{width:52%}.dynamic-form-row .form-field-width-53{width:53%}.dynamic-form-row .form-field-width-54{width:54%}.dynamic-form-row .form-field-width-55{width:55%}.dynamic-form-row .form-field-width-56{width:56%}.dynamic-form-row .form-field-width-57{width:57%}.dynamic-form-row .form-field-width-58{width:58%}.dynamic-form-row .form-field-width-59{width:59%}.dynamic-form-row .form-field-width-60{width:60%}.dynamic-form-row .form-field-width-61{width:61%}.dynamic-form-row .form-field-width-62{width:62%}.dynamic-form-row .form-field-width-63{width:63%}.dynamic-form-row .form-field-width-64{width:64%}.dynamic-form-row .form-field-width-65{width:65%}.dynamic-form-row .form-field-width-66{width:66%}.dynamic-form-row .form-field-width-67{width:67%}.dynamic-form-row .form-field-width-68{width:68%}.dynamic-form-row .form-field-width-69{width:69%}.dynamic-form-row .form-field-width-70{width:70%}.dynamic-form-row .form-field-width-71{width:71%}.dynamic-form-row .form-field-width-72{width:72%}.dynamic-form-row .form-field-width-73{width:73%}.dynamic-form-row .form-field-width-74{width:74%}.dynamic-form-row .form-field-width-75{width:75%}.dynamic-form-row .form-field-width-76{width:76%}.dynamic-form-row .form-field-width-77{width:77%}.dynamic-form-row .form-field-width-78{width:78%}.dynamic-form-row .form-field-width-79{width:79%}.dynamic-form-row .form-field-width-80{width:80%}.dynamic-form-row .form-field-width-81{width:81%}.dynamic-form-row .form-field-width-82{width:82%}.dynamic-form-row .form-field-width-83{width:83%}.dynamic-form-row .form-field-width-84{width:84%}.dynamic-form-row .form-field-width-85{width:85%}.dynamic-form-row .form-field-width-86{width:86%}.dynamic-form-row .form-field-width-87{width:87%}.dynamic-form-row .form-field-width-88{width:88%}.dynamic-form-row .form-field-width-89{width:89%}.dynamic-form-row .form-field-width-90{width:90%}.dynamic-form-row .form-field-width-91{width:91%}.dynamic-form-row .form-field-width-92{width:92%}.dynamic-form-row .form-field-width-93{width:93%}.dynamic-form-row .form-field-width-94{width:94%}.dynamic-form-row .form-field-width-95{width:95%}.dynamic-form-row .form-field-width-96{width:96%}.dynamic-form-row .form-field-width-97{width:97%}.dynamic-form-row .form-field-width-98{width:98%}.dynamic-form-row .form-field-width-99{width:99%}.dynamic-form-row .form-field-width-100{width:100%}\n"] }]
|
|
894
|
+
}], propDecorators: { group: [{
|
|
858
895
|
type: Input,
|
|
859
896
|
args: [{ required: true }]
|
|
860
|
-
}],
|
|
897
|
+
}], formConfig: [{
|
|
898
|
+
type: Input,
|
|
899
|
+
args: [{ required: true }]
|
|
900
|
+
}], change: [{
|
|
861
901
|
type: Output
|
|
862
902
|
}] } });
|
|
863
903
|
|
|
@@ -869,5 +909,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
869
909
|
* Generated bundle index. Do not edit.
|
|
870
910
|
*/
|
|
871
911
|
|
|
872
|
-
export { DYNAMIC_FORM_FIELD_BUTTON, DYNAMIC_FORM_FIELD_CHECKBOX, DYNAMIC_FORM_FIELD_INPUT, DYNAMIC_FORM_FIELD_MAP_FN, DYNAMIC_FORM_FIELD_READONLY, DYNAMIC_FORM_FIELD_SELECT, DYNAMIC_FORM_FIELD_TEXTAREA, DynamicButton, DynamicCheckbox, DynamicFormComponent,
|
|
912
|
+
export { DYNAMIC_FORM_FIELD_BUTTON, DYNAMIC_FORM_FIELD_BUTTON_TOGGLES, DYNAMIC_FORM_FIELD_CHECKBOX, DYNAMIC_FORM_FIELD_INPUT, DYNAMIC_FORM_FIELD_MAP_FN, DYNAMIC_FORM_FIELD_READONLY, DYNAMIC_FORM_FIELD_SELECT, DYNAMIC_FORM_FIELD_TEXTAREA, DynamicButton, DynamicButtonToggles, DynamicCheckbox, DynamicFormComponent, DynamicFormFieldBase, DynamicFormFieldModel, DynamicFormFieldOptionModel, DynamicFormFieldValueModel, DynamicFormService, DynamicFormValidators, DynamicInput, DynamicReadonly, DynamicSelect, DynamicTextarea, RelationActionType, RelationOperator };
|
|
873
913
|
//# sourceMappingURL=olafvv-ngx-dynamic-form.mjs.map
|