@ngx-formly/core 6.3.10 → 7.0.0-alpha.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.
Files changed (121) hide show
  1. package/README.md +1 -0
  2. package/esm2022/json-schema/formly-json-schema.service.mjs +628 -0
  3. package/esm2022/lib/components/formly.field.mjs +292 -0
  4. package/esm2022/lib/components/formly.form.mjs +164 -0
  5. package/{esm2020 → esm2022}/lib/components/formly.template.mjs +7 -7
  6. package/esm2022/lib/core.config.mjs +36 -0
  7. package/esm2022/lib/core.mjs +20 -0
  8. package/esm2022/lib/core.module.mjs +74 -0
  9. package/esm2022/lib/extensions/core/core.mjs +148 -0
  10. package/esm2022/lib/extensions/field-expression/field-expression.mjs +250 -0
  11. package/esm2022/lib/extensions/field-expression/utils.mjs +17 -0
  12. package/esm2022/lib/extensions/field-form/field-form.mjs +141 -0
  13. package/esm2022/lib/extensions/field-form/utils.mjs +100 -0
  14. package/esm2022/lib/extensions/index.mjs +2 -0
  15. package/esm2022/lib/models/fieldconfig.cache.mjs +2 -0
  16. package/esm2022/lib/models/fieldconfig.mjs +2 -0
  17. package/esm2022/lib/services/formly.builder.mjs +100 -0
  18. package/esm2022/lib/services/formly.config.mjs +229 -0
  19. package/esm2022/lib/templates/field-array.type.mjs +84 -0
  20. package/{esm2020 → esm2022}/lib/templates/field-template.type.mjs +9 -9
  21. package/esm2022/lib/templates/field.type.mjs +57 -0
  22. package/{esm2020 → esm2022}/lib/templates/field.wrapper.mjs +4 -4
  23. package/esm2022/lib/templates/formly.attributes.mjs +187 -0
  24. package/{esm2020 → esm2022}/lib/templates/formly.group.mjs +8 -8
  25. package/{esm2020 → esm2022}/lib/templates/formly.validation-message.mjs +4 -4
  26. package/esm2022/lib/utils.mjs +312 -0
  27. package/esm2022/preset/preset.config.mjs +11 -0
  28. package/esm2022/preset/preset.module.mjs +18 -0
  29. package/{esm2020 → esm2022}/select/select-options.pipe.mjs +4 -4
  30. package/{esm2020 → esm2022}/select/select.module.mjs +5 -5
  31. package/{esm2020 → esm2022}/testing/component-factory.mjs +5 -4
  32. package/{fesm2020 → fesm2022}/ngx-formly-core-json-schema.mjs +6 -6
  33. package/fesm2022/ngx-formly-core-json-schema.mjs.map +1 -0
  34. package/{fesm2020 → fesm2022}/ngx-formly-core-preset.mjs +14 -19
  35. package/fesm2022/ngx-formly-core-preset.mjs.map +1 -0
  36. package/{fesm2020 → fesm2022}/ngx-formly-core-select.mjs +7 -7
  37. package/{fesm2020 → fesm2022}/ngx-formly-core-select.mjs.map +1 -1
  38. package/{fesm2020 → fesm2022}/ngx-formly-core-testing.mjs +4 -3
  39. package/fesm2022/ngx-formly-core-testing.mjs.map +1 -0
  40. package/{fesm2020 → fesm2022}/ngx-formly-core.mjs +1751 -1707
  41. package/fesm2022/ngx-formly-core.mjs.map +1 -0
  42. package/lib/components/formly.field.d.ts +5 -1
  43. package/lib/components/formly.form.d.ts +8 -4
  44. package/lib/components/formly.template.d.ts +1 -1
  45. package/lib/core.config.d.ts +10 -0
  46. package/lib/core.d.ts +4 -3
  47. package/lib/core.module.d.ts +2 -5
  48. package/lib/extensions/field-expression/utils.d.ts +1 -1
  49. package/lib/extensions/index.d.ts +1 -0
  50. package/lib/models/config.d.ts +1 -1
  51. package/lib/models/fieldconfig.cache.d.ts +3 -3
  52. package/lib/models/fieldconfig.d.ts +8 -7
  53. package/lib/services/formly.builder.d.ts +5 -5
  54. package/lib/services/formly.config.d.ts +2 -6
  55. package/lib/templates/field-array.type.d.ts +3 -3
  56. package/lib/templates/field-template.type.d.ts +1 -1
  57. package/lib/templates/field.type.d.ts +5 -5
  58. package/lib/templates/field.wrapper.d.ts +1 -1
  59. package/lib/templates/formly.attributes.d.ts +1 -1
  60. package/lib/templates/formly.group.d.ts +1 -1
  61. package/lib/templates/formly.validation-message.d.ts +1 -1
  62. package/lib/utils.d.ts +3 -3
  63. package/package.json +23 -37
  64. package/preset/preset.config.d.ts +2 -0
  65. package/select/select-options.pipe.d.ts +1 -1
  66. package/esm2020/json-schema/formly-json-schema.service.mjs +0 -628
  67. package/esm2020/lib/components/formly.field.mjs +0 -284
  68. package/esm2020/lib/components/formly.form.mjs +0 -148
  69. package/esm2020/lib/core.mjs +0 -19
  70. package/esm2020/lib/core.module.mjs +0 -91
  71. package/esm2020/lib/extensions/core/core.mjs +0 -148
  72. package/esm2020/lib/extensions/field-expression/field-expression.mjs +0 -250
  73. package/esm2020/lib/extensions/field-expression/utils.mjs +0 -17
  74. package/esm2020/lib/extensions/field-form/field-form.mjs +0 -141
  75. package/esm2020/lib/extensions/field-form/utils.mjs +0 -100
  76. package/esm2020/lib/models/fieldconfig.cache.mjs +0 -2
  77. package/esm2020/lib/models/fieldconfig.mjs +0 -2
  78. package/esm2020/lib/services/formly.builder.mjs +0 -93
  79. package/esm2020/lib/services/formly.config.mjs +0 -229
  80. package/esm2020/lib/templates/field-array.type.mjs +0 -84
  81. package/esm2020/lib/templates/field.type.mjs +0 -57
  82. package/esm2020/lib/templates/formly.attributes.mjs +0 -187
  83. package/esm2020/lib/utils.mjs +0 -312
  84. package/esm2020/preset/preset.module.mjs +0 -32
  85. package/fesm2015/ngx-formly-core-json-schema.mjs +0 -615
  86. package/fesm2015/ngx-formly-core-json-schema.mjs.map +0 -1
  87. package/fesm2015/ngx-formly-core-preset.mjs +0 -69
  88. package/fesm2015/ngx-formly-core-preset.mjs.map +0 -1
  89. package/fesm2015/ngx-formly-core-select.mjs +0 -120
  90. package/fesm2015/ngx-formly-core-select.mjs.map +0 -1
  91. package/fesm2015/ngx-formly-core-testing.mjs +0 -87
  92. package/fesm2015/ngx-formly-core-testing.mjs.map +0 -1
  93. package/fesm2015/ngx-formly-core.mjs +0 -2418
  94. package/fesm2015/ngx-formly-core.mjs.map +0 -1
  95. package/fesm2020/ngx-formly-core-json-schema.mjs.map +0 -1
  96. package/fesm2020/ngx-formly-core-preset.mjs.map +0 -1
  97. package/fesm2020/ngx-formly-core-testing.mjs.map +0 -1
  98. package/fesm2020/ngx-formly-core.mjs.map +0 -1
  99. package/json-schema/package.json +0 -10
  100. package/preset/package.json +0 -10
  101. package/select/package.json +0 -10
  102. package/testing/package.json +0 -10
  103. /package/{esm2020 → esm2022}/json-schema/ngx-formly-core-json-schema.mjs +0 -0
  104. /package/{esm2020 → esm2022}/json-schema/public_api.mjs +0 -0
  105. /package/{esm2020 → esm2022}/lib/extensions/field-validation/field-validation.mjs +0 -0
  106. /package/{esm2020 → esm2022}/lib/models/config.mjs +0 -0
  107. /package/{esm2020 → esm2022}/lib/models/index.mjs +0 -0
  108. /package/{esm2020 → esm2022}/ngx-formly-core.mjs +0 -0
  109. /package/{esm2020 → esm2022}/preset/ngx-formly-core-preset.mjs +0 -0
  110. /package/{esm2020 → esm2022}/preset/preset-substitution.extension.mjs +0 -0
  111. /package/{esm2020 → esm2022}/preset/public_api.mjs +0 -0
  112. /package/{esm2020 → esm2022}/public_api.mjs +0 -0
  113. /package/{esm2020 → esm2022}/select/ngx-formly-core-select.mjs +0 -0
  114. /package/{esm2020 → esm2022}/select/public_api.mjs +0 -0
  115. /package/{esm2020 → esm2022}/testing/ngx-formly-core-testing.mjs +0 -0
  116. /package/{esm2020 → esm2022}/testing/public_api.mjs +0 -0
  117. /package/{ngx-formly-core.d.ts → index.d.ts} +0 -0
  118. /package/json-schema/{ngx-formly-core-json-schema.d.ts → index.d.ts} +0 -0
  119. /package/preset/{ngx-formly-core-preset.d.ts → index.d.ts} +0 -0
  120. /package/select/{ngx-formly-core-select.d.ts → index.d.ts} +0 -0
  121. /package/testing/{ngx-formly-core-testing.d.ts → index.d.ts} +0 -0
@@ -1,2418 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Type, TemplateRef, ComponentRef, ChangeDetectorRef, ɵNoopNgZone, VERSION, InjectionToken, Injectable, Optional, Directive, Input, ViewContainerRef, Component, ViewChild, EventEmitter, ChangeDetectionStrategy, Output, ContentChildren, Inject, ViewChildren, NgModule } from '@angular/core';
3
- import * as i2 from '@angular/forms';
4
- import { AbstractControl, FormGroup, FormArray, FormControl, NgControl, Validators } from '@angular/forms';
5
- import { isObservable, of, merge, Observable, Subject } from 'rxjs';
6
- import { map, distinctUntilChanged, startWith, debounceTime, filter, switchMap, take, tap } from 'rxjs/operators';
7
- import * as i2$1 from '@angular/common';
8
- import { DOCUMENT, CommonModule } from '@angular/common';
9
- import * as i1 from '@angular/platform-browser';
10
- import { __rest } from 'tslib';
11
-
12
- function disableTreeValidityCall(form, callback) {
13
- const _updateTreeValidity = form._updateTreeValidity.bind(form);
14
- form._updateTreeValidity = () => { };
15
- callback();
16
- form._updateTreeValidity = _updateTreeValidity;
17
- }
18
- function getFieldId(formId, field, index) {
19
- if (field.id) {
20
- return field.id;
21
- }
22
- let type = field.type;
23
- if (!type && field.template) {
24
- type = 'template';
25
- }
26
- if (type instanceof Type) {
27
- type = type.prototype.constructor.name;
28
- }
29
- return [formId, type, field.key, index].join('_');
30
- }
31
- function hasKey(field) {
32
- return !isNil(field.key) && field.key !== '' && (!Array.isArray(field.key) || field.key.length > 0);
33
- }
34
- function getKeyPath(field) {
35
- var _a;
36
- if (!hasKey(field)) {
37
- return [];
38
- }
39
- /* We store the keyPath in the field for performance reasons. This function will be called frequently. */
40
- if (((_a = field._keyPath) === null || _a === void 0 ? void 0 : _a.key) !== field.key) {
41
- let path = [];
42
- if (typeof field.key === 'string') {
43
- const key = field.key.indexOf('[') === -1 ? field.key : field.key.replace(/\[(\w+)\]/g, '.$1');
44
- path = key.indexOf('.') !== -1 ? key.split('.') : [key];
45
- }
46
- else if (Array.isArray(field.key)) {
47
- path = field.key.slice(0);
48
- }
49
- else {
50
- path = [`${field.key}`];
51
- }
52
- defineHiddenProp(field, '_keyPath', { key: field.key, path });
53
- }
54
- return field._keyPath.path.slice(0);
55
- }
56
- const FORMLY_VALIDATORS = ['required', 'pattern', 'minLength', 'maxLength', 'min', 'max'];
57
- function assignFieldValue(field, value) {
58
- let paths = getKeyPath(field);
59
- if (paths.length === 0) {
60
- return;
61
- }
62
- let root = field;
63
- while (root.parent) {
64
- root = root.parent;
65
- paths = [...getKeyPath(root), ...paths];
66
- }
67
- if (value === undefined && field.resetOnHide) {
68
- const k = paths.pop();
69
- const m = paths.reduce((model, path) => model[path] || {}, root.model);
70
- delete m[k];
71
- return;
72
- }
73
- assignModelValue(root.model, paths, value);
74
- }
75
- function assignModelValue(model, paths, value) {
76
- for (let i = 0; i < paths.length - 1; i++) {
77
- const path = paths[i];
78
- if (!model[path] || !isObject(model[path])) {
79
- model[path] = /^\d+$/.test(paths[i + 1]) ? [] : {};
80
- }
81
- model = model[path];
82
- }
83
- model[paths[paths.length - 1]] = clone(value);
84
- }
85
- function getFieldValue(field) {
86
- let model = field.parent ? field.parent.model : field.model;
87
- for (const path of getKeyPath(field)) {
88
- if (!model) {
89
- return model;
90
- }
91
- model = model[path];
92
- }
93
- return model;
94
- }
95
- function reverseDeepMerge(dest, ...args) {
96
- args.forEach((src) => {
97
- for (const srcArg in src) {
98
- if (isNil(dest[srcArg]) || isBlankString(dest[srcArg])) {
99
- dest[srcArg] = clone(src[srcArg]);
100
- }
101
- else if (objAndSameType(dest[srcArg], src[srcArg])) {
102
- reverseDeepMerge(dest[srcArg], src[srcArg]);
103
- }
104
- }
105
- });
106
- return dest;
107
- }
108
- // check a value is null or undefined
109
- function isNil(value) {
110
- return value == null;
111
- }
112
- function isUndefined(value) {
113
- return value === undefined;
114
- }
115
- function isBlankString(value) {
116
- return value === '';
117
- }
118
- function isFunction(value) {
119
- return typeof value === 'function';
120
- }
121
- function objAndSameType(obj1, obj2) {
122
- return (isObject(obj1) &&
123
- isObject(obj2) &&
124
- Object.getPrototypeOf(obj1) === Object.getPrototypeOf(obj2) &&
125
- !(Array.isArray(obj1) || Array.isArray(obj2)));
126
- }
127
- function isObject(x) {
128
- return x != null && typeof x === 'object';
129
- }
130
- function isPromise(obj) {
131
- return !!obj && typeof obj.then === 'function';
132
- }
133
- function clone(value) {
134
- var _a;
135
- if (!isObject(value) ||
136
- isObservable(value) ||
137
- value instanceof TemplateRef ||
138
- /* instanceof SafeHtmlImpl */ value.changingThisBreaksApplicationSecurity ||
139
- ['RegExp', 'FileList', 'File', 'Blob'].indexOf((_a = value.constructor) === null || _a === void 0 ? void 0 : _a.name) !== -1) {
140
- return value;
141
- }
142
- if (value instanceof Set) {
143
- return new Set(value);
144
- }
145
- if (value instanceof Map) {
146
- return new Map(value);
147
- }
148
- if (value instanceof Uint8Array) {
149
- return new Uint8Array(value);
150
- }
151
- if (value instanceof Uint16Array) {
152
- return new Uint16Array(value);
153
- }
154
- if (value instanceof Uint32Array) {
155
- return new Uint32Array(value);
156
- }
157
- // https://github.com/moment/moment/blob/master/moment.js#L252
158
- if (value._isAMomentObject && isFunction(value.clone)) {
159
- return value.clone();
160
- }
161
- if (value instanceof AbstractControl) {
162
- return null;
163
- }
164
- if (value instanceof Date) {
165
- return new Date(value.getTime());
166
- }
167
- if (Array.isArray(value)) {
168
- return value.slice(0).map((v) => clone(v));
169
- }
170
- // best way to clone a js object maybe
171
- // https://stackoverflow.com/questions/41474986/how-to-clone-a-javascript-es6-class-instance
172
- const proto = Object.getPrototypeOf(value);
173
- let c = Object.create(proto);
174
- c = Object.setPrototypeOf(c, proto);
175
- // need to make a deep copy so we dont use Object.assign
176
- // also Object.assign wont copy property descriptor exactly
177
- return Object.keys(value).reduce((newVal, prop) => {
178
- const propDesc = Object.getOwnPropertyDescriptor(value, prop);
179
- if (propDesc.get) {
180
- Object.defineProperty(newVal, prop, propDesc);
181
- }
182
- else {
183
- newVal[prop] = clone(value[prop]);
184
- }
185
- return newVal;
186
- }, c);
187
- }
188
- function defineHiddenProp(field, prop, defaultValue) {
189
- Object.defineProperty(field, prop, { enumerable: false, writable: true, configurable: true });
190
- field[prop] = defaultValue;
191
- }
192
- function observeDeep(source, paths, setFn) {
193
- let observers = [];
194
- const unsubscribe = () => {
195
- observers.forEach((observer) => observer());
196
- observers = [];
197
- };
198
- const observer = observe(source, paths, ({ firstChange, currentValue }) => {
199
- !firstChange && setFn();
200
- unsubscribe();
201
- if (isObject(currentValue) && currentValue.constructor.name === 'Object') {
202
- Object.keys(currentValue).forEach((prop) => {
203
- observers.push(observeDeep(source, [...paths, prop], setFn));
204
- });
205
- }
206
- });
207
- return () => {
208
- observer.unsubscribe();
209
- unsubscribe();
210
- };
211
- }
212
- function observe(o, paths, setFn) {
213
- if (!o._observers) {
214
- defineHiddenProp(o, '_observers', {});
215
- }
216
- let target = o;
217
- for (let i = 0; i < paths.length - 1; i++) {
218
- if (!target[paths[i]] || !isObject(target[paths[i]])) {
219
- target[paths[i]] = /^\d+$/.test(paths[i + 1]) ? [] : {};
220
- }
221
- target = target[paths[i]];
222
- }
223
- const key = paths[paths.length - 1];
224
- const prop = paths.join('.');
225
- if (!o._observers[prop]) {
226
- o._observers[prop] = { value: target[key], onChange: [] };
227
- }
228
- const state = o._observers[prop];
229
- if (target[key] !== state.value) {
230
- state.value = target[key];
231
- }
232
- if (setFn && state.onChange.indexOf(setFn) === -1) {
233
- state.onChange.push(setFn);
234
- setFn({ currentValue: state.value, firstChange: true });
235
- if (state.onChange.length >= 1 && isObject(target)) {
236
- const { enumerable } = Object.getOwnPropertyDescriptor(target, key) || { enumerable: true };
237
- Object.defineProperty(target, key, {
238
- enumerable,
239
- configurable: true,
240
- get: () => state.value,
241
- set: (currentValue) => {
242
- if (currentValue !== state.value) {
243
- const previousValue = state.value;
244
- state.value = currentValue;
245
- state.onChange.forEach((changeFn) => changeFn({ previousValue, currentValue, firstChange: false }));
246
- }
247
- },
248
- });
249
- }
250
- }
251
- return {
252
- setValue(currentValue, emitEvent = true) {
253
- if (currentValue === state.value) {
254
- return;
255
- }
256
- const previousValue = state.value;
257
- state.value = currentValue;
258
- state.onChange.forEach((changeFn) => {
259
- if (changeFn !== setFn && emitEvent) {
260
- changeFn({ previousValue, currentValue, firstChange: false });
261
- }
262
- });
263
- },
264
- unsubscribe() {
265
- state.onChange = state.onChange.filter((changeFn) => changeFn !== setFn);
266
- if (state.onChange.length === 0) {
267
- delete o._observers[prop];
268
- }
269
- },
270
- };
271
- }
272
- function getField(f, key) {
273
- key = (Array.isArray(key) ? key.join('.') : key);
274
- if (!f.fieldGroup) {
275
- return undefined;
276
- }
277
- for (let i = 0, len = f.fieldGroup.length; i < len; i++) {
278
- const c = f.fieldGroup[i];
279
- const k = (Array.isArray(c.key) ? c.key.join('.') : c.key);
280
- if (k === key) {
281
- return c;
282
- }
283
- if (c.fieldGroup && (isNil(k) || key.indexOf(`${k}.`) === 0)) {
284
- const field = getField(c, isNil(k) ? key : key.slice(k.length + 1));
285
- if (field) {
286
- return field;
287
- }
288
- }
289
- }
290
- return undefined;
291
- }
292
- function markFieldForCheck(field) {
293
- var _a;
294
- (_a = field._componentRefs) === null || _a === void 0 ? void 0 : _a.forEach((ref) => {
295
- // NOTE: we cannot use ref.changeDetectorRef, see https://github.com/ngx-formly/ngx-formly/issues/2191
296
- if (ref instanceof ComponentRef) {
297
- const changeDetectorRef = ref.injector.get(ChangeDetectorRef);
298
- changeDetectorRef.markForCheck();
299
- }
300
- else {
301
- ref.markForCheck();
302
- }
303
- });
304
- }
305
- function isNoopNgZone(ngZone) {
306
- return ngZone instanceof ɵNoopNgZone;
307
- }
308
- function isHiddenField(field) {
309
- const isHidden = (f) => { var _a; return f.hide || ((_a = f.expressions) === null || _a === void 0 ? void 0 : _a.hide) || f.hideExpression; };
310
- let setDefaultValue = !field.resetOnHide || !isHidden(field);
311
- if (!isHidden(field) && field.resetOnHide) {
312
- let parent = field.parent;
313
- while (parent && !isHidden(parent)) {
314
- parent = parent.parent;
315
- }
316
- setDefaultValue = !parent || !isHidden(parent);
317
- }
318
- return !setDefaultValue;
319
- }
320
- function isSignalRequired() {
321
- return +VERSION.major >= 18 && +VERSION.minor >= 1;
322
- }
323
-
324
- /**
325
- * An InjectionToken for registering additional formly config options (types, wrappers ...).
326
- */
327
- const FORMLY_CONFIG = new InjectionToken('FORMLY_CONFIG');
328
- /**
329
- * Maintains list of formly config options. This can be used to register new field type.
330
- */
331
- class FormlyConfig {
332
- constructor() {
333
- this.types = {};
334
- this.validators = {};
335
- this.wrappers = {};
336
- this.messages = {};
337
- this.extras = {
338
- checkExpressionOn: 'modelChange',
339
- lazyRender: true,
340
- resetFieldOnHide: true,
341
- renderFormlyFieldElement: true,
342
- showError(field) {
343
- var _a, _b, _c, _d;
344
- return (((_a = field.formControl) === null || _a === void 0 ? void 0 : _a.invalid) &&
345
- (((_b = field.formControl) === null || _b === void 0 ? void 0 : _b.touched) || ((_c = field.options.parentForm) === null || _c === void 0 ? void 0 : _c.submitted) || !!((_d = field.field.validation) === null || _d === void 0 ? void 0 : _d.show)));
346
- },
347
- };
348
- this.extensions = {};
349
- this.presets = {};
350
- this.extensionsByPriority = {};
351
- }
352
- addConfig(config) {
353
- if (config.types) {
354
- config.types.forEach((type) => this.setType(type));
355
- }
356
- if (config.validators) {
357
- config.validators.forEach((validator) => this.setValidator(validator));
358
- }
359
- if (config.wrappers) {
360
- config.wrappers.forEach((wrapper) => this.setWrapper(wrapper));
361
- }
362
- if (config.validationMessages) {
363
- config.validationMessages.forEach((validation) => this.addValidatorMessage(validation.name, validation.message));
364
- }
365
- if (config.extensions) {
366
- this.setSortedExtensions(config.extensions);
367
- }
368
- if (config.extras) {
369
- this.extras = Object.assign(Object.assign({}, this.extras), config.extras);
370
- }
371
- if (config.presets) {
372
- this.presets = Object.assign(Object.assign({}, this.presets), config.presets.reduce((acc, curr) => (Object.assign(Object.assign({}, acc), { [curr.name]: curr.config })), {}));
373
- }
374
- }
375
- /**
376
- * Allows you to specify a custom type which you can use in your field configuration.
377
- * You can pass an object of options, or an array of objects of options.
378
- */
379
- setType(options) {
380
- if (Array.isArray(options)) {
381
- options.forEach((option) => this.setType(option));
382
- }
383
- else {
384
- if (!this.types[options.name]) {
385
- this.types[options.name] = { name: options.name };
386
- }
387
- ['component', 'extends', 'defaultOptions', 'wrappers'].forEach((prop) => {
388
- if (options.hasOwnProperty(prop)) {
389
- this.types[options.name][prop] = options[prop];
390
- }
391
- });
392
- }
393
- }
394
- getType(name, throwIfNotFound = false) {
395
- if (name instanceof Type) {
396
- return { component: name, name: name.prototype.constructor.name };
397
- }
398
- if (!this.types[name]) {
399
- if (throwIfNotFound) {
400
- throw new Error(`[Formly Error] The type "${name}" could not be found. Please make sure that is registered through the FormlyModule declaration.`);
401
- }
402
- return null;
403
- }
404
- this.mergeExtendedType(name);
405
- return this.types[name];
406
- }
407
- /** @ignore */
408
- getMergedField(field = {}) {
409
- var _a;
410
- const type = this.getType(field.type);
411
- if (!type) {
412
- return;
413
- }
414
- if (type.defaultOptions) {
415
- reverseDeepMerge(field, type.defaultOptions);
416
- }
417
- const extendDefaults = type.extends && this.getType(type.extends).defaultOptions;
418
- if (extendDefaults) {
419
- reverseDeepMerge(field, extendDefaults);
420
- }
421
- if (field === null || field === void 0 ? void 0 : field.optionsTypes) {
422
- field.optionsTypes.forEach((option) => {
423
- const defaultOptions = this.getType(option).defaultOptions;
424
- if (defaultOptions) {
425
- reverseDeepMerge(field, defaultOptions);
426
- }
427
- });
428
- }
429
- const componentRef = this.resolveFieldTypeRef(field);
430
- if ((_a = componentRef === null || componentRef === void 0 ? void 0 : componentRef.instance) === null || _a === void 0 ? void 0 : _a.defaultOptions) {
431
- reverseDeepMerge(field, componentRef.instance.defaultOptions);
432
- }
433
- if (!field.wrappers && type.wrappers) {
434
- field.wrappers = [...type.wrappers];
435
- }
436
- }
437
- /** @ignore @internal */
438
- resolveFieldTypeRef(field = {}) {
439
- const type = this.getType(field.type);
440
- if (!type) {
441
- return null;
442
- }
443
- if (!type.component || type._componentRef) {
444
- return type._componentRef;
445
- }
446
- const { _viewContainerRef, _injector } = field.options;
447
- if (!_viewContainerRef || !_injector) {
448
- return null;
449
- }
450
- const componentRef = _viewContainerRef.createComponent(type.component, { injector: _injector });
451
- defineHiddenProp(type, '_componentRef', componentRef);
452
- try {
453
- componentRef.destroy();
454
- }
455
- catch (e) {
456
- console.error(`An error occurred while destroying the Formly component type "${field.type}"`, e);
457
- }
458
- return type._componentRef;
459
- }
460
- setWrapper(options) {
461
- this.wrappers[options.name] = options;
462
- if (options.types) {
463
- options.types.forEach((type) => {
464
- this.setTypeWrapper(type, options.name);
465
- });
466
- }
467
- }
468
- getWrapper(name) {
469
- if (name instanceof Type) {
470
- return { component: name, name: name.prototype.constructor.name };
471
- }
472
- if (!this.wrappers[name]) {
473
- throw new Error(`[Formly Error] The wrapper "${name}" could not be found. Please make sure that is registered through the FormlyModule declaration.`);
474
- }
475
- return this.wrappers[name];
476
- }
477
- /** @ignore */
478
- setTypeWrapper(type, name) {
479
- if (!this.types[type]) {
480
- this.types[type] = {};
481
- }
482
- if (!this.types[type].wrappers) {
483
- this.types[type].wrappers = [];
484
- }
485
- if (this.types[type].wrappers.indexOf(name) === -1) {
486
- this.types[type].wrappers.push(name);
487
- }
488
- }
489
- setValidator(options) {
490
- this.validators[options.name] = options;
491
- }
492
- getValidator(name) {
493
- if (!this.validators[name]) {
494
- throw new Error(`[Formly Error] The validator "${name}" could not be found. Please make sure that is registered through the FormlyModule declaration.`);
495
- }
496
- return this.validators[name];
497
- }
498
- addValidatorMessage(name, message) {
499
- this.messages[name] = message;
500
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
501
- const deprecated = { minlength: 'minLength', maxlength: 'maxLength' };
502
- if (deprecated[name]) {
503
- console.warn(`Formly deprecation: passing validation messages key '${name}' is deprecated since v6.0, use '${deprecated[name]}' instead.`);
504
- this.messages[deprecated[name]] = message;
505
- }
506
- }
507
- }
508
- getValidatorMessage(name) {
509
- return this.messages[name];
510
- }
511
- setSortedExtensions(extensionOptions) {
512
- // insert new extensions, grouped by priority
513
- extensionOptions.forEach((extensionOption) => {
514
- var _a;
515
- const priority = (_a = extensionOption.priority) !== null && _a !== void 0 ? _a : 1;
516
- this.extensionsByPriority[priority] = Object.assign(Object.assign({}, this.extensionsByPriority[priority]), { [extensionOption.name]: extensionOption.extension });
517
- });
518
- // flatten extensions object with sorted keys
519
- this.extensions = Object.keys(this.extensionsByPriority)
520
- .map(Number)
521
- .sort((a, b) => a - b)
522
- .reduce((acc, prio) => (Object.assign(Object.assign({}, acc), this.extensionsByPriority[prio])), {});
523
- }
524
- mergeExtendedType(name) {
525
- if (!this.types[name].extends) {
526
- return;
527
- }
528
- const extendedType = this.getType(this.types[name].extends);
529
- if (!this.types[name].component) {
530
- this.types[name].component = extendedType.component;
531
- }
532
- if (!this.types[name].wrappers) {
533
- this.types[name].wrappers = extendedType.wrappers;
534
- }
535
- }
536
- }
537
- FormlyConfig.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
538
- FormlyConfig.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyConfig, providedIn: 'root' });
539
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyConfig, decorators: [{
540
- type: Injectable,
541
- args: [{ providedIn: 'root' }]
542
- }] });
543
-
544
- class FormlyFormBuilder {
545
- constructor(config, injector, viewContainerRef, parentForm) {
546
- this.config = config;
547
- this.injector = injector;
548
- this.viewContainerRef = viewContainerRef;
549
- this.parentForm = parentForm;
550
- }
551
- buildForm(form, fieldGroup = [], model, options) {
552
- this.build({ fieldGroup, model, form, options });
553
- }
554
- build(field) {
555
- if (!this.config.extensions.core) {
556
- throw new Error('NgxFormly: missing `forRoot()` call. use `forRoot()` when registering the `FormlyModule`.');
557
- }
558
- if (!field.parent) {
559
- this._setOptions(field);
560
- }
561
- disableTreeValidityCall(field.form, () => {
562
- var _a, _b, _c;
563
- this._build(field);
564
- // TODO: add test for https://github.com/ngx-formly/ngx-formly/issues/3910
565
- if (!field.parent || field.fieldArray) {
566
- // detect changes early to avoid reset value by hidden fields
567
- const options = field.options;
568
- if (field.parent && isHiddenField(field)) {
569
- // when hide is used in expression set defaul value will not be set until detect hide changes
570
- // which causes default value not set on new item is added
571
- (_a = options._hiddenFieldsForCheck) === null || _a === void 0 ? void 0 : _a.push({ field, default: false });
572
- }
573
- (_b = options.checkExpressions) === null || _b === void 0 ? void 0 : _b.call(options, field, true);
574
- (_c = options._detectChanges) === null || _c === void 0 ? void 0 : _c.call(options, field);
575
- }
576
- });
577
- }
578
- _build(field) {
579
- var _a;
580
- if (!field) {
581
- return;
582
- }
583
- const extensions = Object.values(this.config.extensions);
584
- extensions.forEach((extension) => { var _a; return (_a = extension.prePopulate) === null || _a === void 0 ? void 0 : _a.call(extension, field); });
585
- extensions.forEach((extension) => { var _a; return (_a = extension.onPopulate) === null || _a === void 0 ? void 0 : _a.call(extension, field); });
586
- (_a = field.fieldGroup) === null || _a === void 0 ? void 0 : _a.forEach((f) => this._build(f));
587
- extensions.forEach((extension) => { var _a; return (_a = extension.postPopulate) === null || _a === void 0 ? void 0 : _a.call(extension, field); });
588
- }
589
- _setOptions(field) {
590
- field.form = field.form || new FormGroup({});
591
- field.model = field.model || {};
592
- field.options = field.options || {};
593
- const options = field.options;
594
- if (!options._viewContainerRef) {
595
- defineHiddenProp(options, '_viewContainerRef', this.viewContainerRef);
596
- }
597
- if (!options._injector) {
598
- defineHiddenProp(options, '_injector', this.injector);
599
- }
600
- if (!options.build) {
601
- options._buildForm = () => {
602
- console.warn(`Formly: 'options._buildForm' is deprecated since v6.0, use 'options.build' instead.`);
603
- this.build(field);
604
- };
605
- options.build = (f = field) => {
606
- this.build(f);
607
- return f;
608
- };
609
- }
610
- if (!options.parentForm && this.parentForm) {
611
- defineHiddenProp(options, 'parentForm', this.parentForm);
612
- if (!isSignalRequired()) {
613
- observe(options, ['parentForm', 'submitted'], ({ firstChange }) => {
614
- if (!firstChange) {
615
- options.detectChanges(field);
616
- }
617
- });
618
- }
619
- }
620
- }
621
- }
622
- FormlyFormBuilder.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyFormBuilder, deps: [{ token: FormlyConfig }, { token: i0.Injector }, { token: i0.ViewContainerRef, optional: true }, { token: i2.FormGroupDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
623
- FormlyFormBuilder.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyFormBuilder, providedIn: 'root' });
624
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyFormBuilder, decorators: [{
625
- type: Injectable,
626
- args: [{ providedIn: 'root' }]
627
- }], ctorParameters: function () {
628
- return [{ type: FormlyConfig }, { type: i0.Injector }, { type: i0.ViewContainerRef, decorators: [{
629
- type: Optional
630
- }] }, { type: i2.FormGroupDirective, decorators: [{
631
- type: Optional
632
- }] }];
633
- } });
634
-
635
- function unregisterControl(field, emitEvent = false) {
636
- const control = field.formControl;
637
- const fieldIndex = control._fields ? control._fields.indexOf(field) : -1;
638
- if (fieldIndex !== -1) {
639
- control._fields.splice(fieldIndex, 1);
640
- }
641
- const form = control.parent;
642
- if (!form) {
643
- return;
644
- }
645
- const opts = { emitEvent };
646
- if (form instanceof FormArray) {
647
- const key = form.controls.findIndex((c) => c === control);
648
- if (key !== -1) {
649
- form.removeAt(key, opts);
650
- }
651
- }
652
- else if (form instanceof FormGroup) {
653
- const paths = getKeyPath(field);
654
- const key = paths[paths.length - 1];
655
- if (form.get([key]) === control) {
656
- form.removeControl(key, opts);
657
- }
658
- }
659
- control.setParent(null);
660
- }
661
- function findControl(field) {
662
- var _a;
663
- if (field.formControl) {
664
- return field.formControl;
665
- }
666
- if (field.shareFormControl === false) {
667
- return null;
668
- }
669
- return (_a = field.form) === null || _a === void 0 ? void 0 : _a.get(getKeyPath(field));
670
- }
671
- function registerControl(field, control, emitEvent = false) {
672
- control = control || field.formControl;
673
- if (!control._fields) {
674
- defineHiddenProp(control, '_fields', []);
675
- }
676
- if (control._fields.indexOf(field) === -1) {
677
- control._fields.push(field);
678
- }
679
- if (!field.formControl && control) {
680
- defineHiddenProp(field, 'formControl', control);
681
- control.setValidators(null);
682
- control.setAsyncValidators(null);
683
- field.props.disabled = !!field.props.disabled;
684
- const disabledObserver = observe(field, ['props', 'disabled'], ({ firstChange, currentValue }) => {
685
- if (!firstChange) {
686
- currentValue ? field.formControl.disable() : field.formControl.enable();
687
- }
688
- });
689
- if (control instanceof FormControl) {
690
- control.registerOnDisabledChange(disabledObserver.setValue);
691
- }
692
- }
693
- if (!field.form || !hasKey(field)) {
694
- return;
695
- }
696
- let form = field.form;
697
- const paths = getKeyPath(field);
698
- const value = getFieldValue(field);
699
- if (!(isNil(control.value) && isNil(value)) && control.value !== value && control instanceof FormControl) {
700
- control.patchValue(value);
701
- }
702
- for (let i = 0; i < paths.length - 1; i++) {
703
- const path = paths[i];
704
- if (!form.get([path])) {
705
- form.setControl(path, new FormGroup({}), { emitEvent });
706
- }
707
- form = form.get([path]);
708
- }
709
- const key = paths[paths.length - 1];
710
- if (!field._hide && form.get([key]) !== control) {
711
- form.setControl(key, control, { emitEvent });
712
- }
713
- }
714
- function updateValidity(c, onlySelf = false) {
715
- const status = c.status;
716
- const value = c.value;
717
- c.updateValueAndValidity({ emitEvent: false, onlySelf });
718
- if (status !== c.status) {
719
- c.statusChanges.emit(c.status);
720
- }
721
- if (value !== c.value) {
722
- c.valueChanges.emit(c.value);
723
- }
724
- }
725
- function clearControl(form) {
726
- form === null || form === void 0 ? true : delete form._fields;
727
- form.setValidators(null);
728
- form.setAsyncValidators(null);
729
- if (form instanceof FormGroup || form instanceof FormArray) {
730
- Object.values(form.controls).forEach((c) => clearControl(c));
731
- }
732
- }
733
-
734
- class FormlyTemplate {
735
- constructor(ref) {
736
- this.ref = ref;
737
- }
738
- ngOnChanges() {
739
- this.name = this.name || 'formly-group';
740
- }
741
- }
742
- FormlyTemplate.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyTemplate, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
743
- FormlyTemplate.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: FormlyTemplate, selector: "[formlyTemplate]", inputs: { name: ["formlyTemplate", "name"] }, usesOnChanges: true, ngImport: i0 });
744
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyTemplate, decorators: [{
745
- type: Directive,
746
- args: [{ selector: '[formlyTemplate]' }]
747
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { name: [{
748
- type: Input,
749
- args: ['formlyTemplate']
750
- }] } });
751
- // workarround for https://github.com/angular/angular/issues/43227#issuecomment-904173738
752
- class FormlyFieldTemplates {
753
- }
754
- FormlyFieldTemplates.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyFieldTemplates, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
755
- FormlyFieldTemplates.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyFieldTemplates });
756
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyFieldTemplates, decorators: [{
757
- type: Injectable
758
- }] });
759
-
760
- /**
761
- * The `<formly-field>` component is used to render the UI widget (layout + type) of a given `field`.
762
- */
763
- class FormlyField {
764
- constructor(config, renderer, _elementRef, hostContainerRef, form) {
765
- this.config = config;
766
- this.renderer = renderer;
767
- this._elementRef = _elementRef;
768
- this.hostContainerRef = hostContainerRef;
769
- this.form = form;
770
- this.hostObservers = [];
771
- this.componentRefs = [];
772
- this.hooksObservers = [];
773
- this.detectFieldBuild = false;
774
- this.valueChangesUnsubscribe = () => { };
775
- }
776
- get containerRef() {
777
- return this.config.extras.renderFormlyFieldElement ? this.viewContainerRef : this.hostContainerRef;
778
- }
779
- get elementRef() {
780
- var _a;
781
- if (this.config.extras.renderFormlyFieldElement) {
782
- return this._elementRef;
783
- }
784
- if (((_a = this.componentRefs) === null || _a === void 0 ? void 0 : _a[0]) instanceof ComponentRef) {
785
- return this.componentRefs[0].location;
786
- }
787
- return null;
788
- }
789
- ngAfterContentInit() {
790
- this.triggerHook('afterContentInit');
791
- }
792
- ngAfterViewInit() {
793
- this.triggerHook('afterViewInit');
794
- }
795
- ngDoCheck() {
796
- if (this.detectFieldBuild && this.field && this.field.options) {
797
- this.render();
798
- }
799
- }
800
- ngOnInit() {
801
- this.triggerHook('onInit');
802
- }
803
- ngOnChanges(changes) {
804
- this.triggerHook('onChanges', changes);
805
- }
806
- ngOnDestroy() {
807
- this.resetRefs(this.field);
808
- this.hostObservers.forEach((hostObserver) => hostObserver.unsubscribe());
809
- this.hooksObservers.forEach((unsubscribe) => unsubscribe());
810
- this.valueChangesUnsubscribe();
811
- this.triggerHook('onDestroy');
812
- }
813
- renderField(containerRef, f, wrappers = []) {
814
- var _a, _b, _c;
815
- if (this.containerRef === containerRef) {
816
- this.resetRefs(this.field);
817
- this.containerRef.clear();
818
- wrappers = (_a = this.field) === null || _a === void 0 ? void 0 : _a.wrappers;
819
- }
820
- if ((wrappers === null || wrappers === void 0 ? void 0 : wrappers.length) > 0) {
821
- const [wrapper, ...wps] = wrappers;
822
- const { component } = this.config.getWrapper(wrapper);
823
- const ref = containerRef.createComponent(component);
824
- this.attachComponentRef(ref, f);
825
- observe(ref.instance, ['fieldComponent'], ({ currentValue, previousValue, firstChange }) => {
826
- if (currentValue) {
827
- if (previousValue && previousValue._lContainer === currentValue._lContainer) {
828
- return;
829
- }
830
- const viewRef = previousValue ? previousValue.detach() : null;
831
- if (viewRef && !viewRef.destroyed) {
832
- currentValue.insert(viewRef);
833
- }
834
- else {
835
- this.renderField(currentValue, f, wps);
836
- }
837
- !firstChange && ref.changeDetectorRef.detectChanges();
838
- }
839
- });
840
- }
841
- else if (f === null || f === void 0 ? void 0 : f.type) {
842
- const inlineType = (_c = (_b = this.form) === null || _b === void 0 ? void 0 : _b.templates) === null || _c === void 0 ? void 0 : _c.find((ref) => ref.name === f.type);
843
- let ref;
844
- if (inlineType) {
845
- ref = containerRef.createEmbeddedView(inlineType.ref, { $implicit: f });
846
- }
847
- else {
848
- const { component } = this.config.getType(f.type, true);
849
- ref = containerRef.createComponent(component);
850
- }
851
- this.attachComponentRef(ref, f);
852
- }
853
- }
854
- triggerHook(name, changes) {
855
- var _a, _b;
856
- if (name === 'onInit' || (name === 'onChanges' && changes.field && !changes.field.firstChange)) {
857
- this.valueChangesUnsubscribe();
858
- this.valueChangesUnsubscribe = this.fieldChanges(this.field);
859
- }
860
- if ((_b = (_a = this.field) === null || _a === void 0 ? void 0 : _a.hooks) === null || _b === void 0 ? void 0 : _b[name]) {
861
- if (!changes || changes.field) {
862
- const r = this.field.hooks[name](this.field);
863
- if (isObservable(r) && ['onInit', 'afterContentInit', 'afterViewInit'].indexOf(name) !== -1) {
864
- const sub = r.subscribe();
865
- this.hooksObservers.push(() => sub.unsubscribe());
866
- }
867
- }
868
- }
869
- if (name === 'onChanges' && changes.field) {
870
- this.resetRefs(changes.field.previousValue);
871
- this.render();
872
- }
873
- }
874
- attachComponentRef(ref, field) {
875
- this.componentRefs.push(ref);
876
- field._componentRefs.push(ref);
877
- if (ref instanceof ComponentRef) {
878
- Object.assign(ref.instance, { field });
879
- }
880
- }
881
- render() {
882
- if (!this.field) {
883
- return;
884
- }
885
- // require Formly build
886
- if (!this.field.options) {
887
- this.detectFieldBuild = true;
888
- return;
889
- }
890
- this.detectFieldBuild = false;
891
- this.hostObservers.forEach((hostObserver) => hostObserver.unsubscribe());
892
- this.hostObservers = [
893
- observe(this.field, ['hide'], ({ firstChange, currentValue }) => {
894
- const containerRef = this.containerRef;
895
- if (this.config.extras.lazyRender === false) {
896
- firstChange && this.renderField(containerRef, this.field);
897
- if (!firstChange || (firstChange && currentValue)) {
898
- this.elementRef &&
899
- this.renderer.setStyle(this.elementRef.nativeElement, 'display', currentValue ? 'none' : '');
900
- }
901
- }
902
- else {
903
- if (currentValue) {
904
- containerRef.clear();
905
- if (this.field.className) {
906
- this.renderer.removeAttribute(this.elementRef.nativeElement, 'class');
907
- }
908
- }
909
- else {
910
- this.renderField(containerRef, this.field);
911
- if (this.field.className) {
912
- this.renderer.setAttribute(this.elementRef.nativeElement, 'class', this.field.className);
913
- }
914
- }
915
- }
916
- !firstChange && this.field.options.detectChanges(this.field);
917
- }),
918
- observe(this.field, ['className'], ({ firstChange, currentValue }) => {
919
- if ((!firstChange || (firstChange && currentValue)) &&
920
- (!this.config.extras.lazyRender || this.field.hide !== true)) {
921
- this.elementRef && this.renderer.setAttribute(this.elementRef.nativeElement, 'class', currentValue);
922
- }
923
- }),
924
- ];
925
- if (!isSignalRequired()) {
926
- ['touched', 'pristine', 'status'].forEach((prop) => this.hostObservers.push(observe(this.field, ['formControl', prop], ({ firstChange }) => !firstChange && markFieldForCheck(this.field))));
927
- }
928
- else if (this.field.formControl) {
929
- const events = this.field.formControl.events.subscribe(() => markFieldForCheck(this.field));
930
- this.hostObservers.push(events);
931
- }
932
- }
933
- resetRefs(field) {
934
- if (field) {
935
- if (field._localFields) {
936
- field._localFields = [];
937
- }
938
- else {
939
- defineHiddenProp(this.field, '_localFields', []);
940
- }
941
- if (field._componentRefs) {
942
- field._componentRefs = field._componentRefs.filter((ref) => this.componentRefs.indexOf(ref) === -1);
943
- }
944
- else {
945
- defineHiddenProp(this.field, '_componentRefs', []);
946
- }
947
- }
948
- this.componentRefs = [];
949
- }
950
- fieldChanges(field) {
951
- if (!field) {
952
- return () => { };
953
- }
954
- const propsObserver = observeDeep(field, ['props'], () => field.options.detectChanges(field));
955
- let subscribes = [
956
- () => {
957
- propsObserver();
958
- },
959
- ];
960
- for (const key of Object.keys(field._expressions || {})) {
961
- const expressionObserver = observe(field, ['_expressions', key], ({ currentValue, previousValue }) => {
962
- if (previousValue === null || previousValue === void 0 ? void 0 : previousValue.subscription) {
963
- previousValue.subscription.unsubscribe();
964
- previousValue.subscription = null;
965
- }
966
- if (isObservable(currentValue.value$)) {
967
- currentValue.subscription = currentValue.value$.subscribe();
968
- }
969
- });
970
- subscribes.push(() => {
971
- var _a;
972
- if ((_a = field._expressions[key]) === null || _a === void 0 ? void 0 : _a.subscription) {
973
- field._expressions[key].subscription.unsubscribe();
974
- }
975
- expressionObserver.unsubscribe();
976
- });
977
- }
978
- for (const path of [['focus'], ['template'], ['fieldGroupClassName'], ['validation', 'show']]) {
979
- const fieldObserver = observe(field, path, ({ firstChange }) => !firstChange && field.options.detectChanges(field));
980
- subscribes.push(() => fieldObserver.unsubscribe());
981
- }
982
- if (field.formControl && !field.fieldGroup) {
983
- const control = field.formControl;
984
- let valueChanges = control.valueChanges.pipe(map((value) => {
985
- var _a;
986
- (_a = field.parsers) === null || _a === void 0 ? void 0 : _a.map((parserFn) => (value = parserFn(value, field)));
987
- if (!Object.is(value, field.formControl.value)) {
988
- field.formControl.setValue(value);
989
- }
990
- return value;
991
- }), distinctUntilChanged((x, y) => {
992
- if (x !== y || Array.isArray(x) || isObject(x)) {
993
- return false;
994
- }
995
- return true;
996
- }));
997
- if (control.value !== getFieldValue(field)) {
998
- valueChanges = valueChanges.pipe(startWith(control.value));
999
- }
1000
- const { updateOn, debounce } = field.modelOptions;
1001
- if ((!updateOn || updateOn === 'change') && (debounce === null || debounce === void 0 ? void 0 : debounce.default) > 0) {
1002
- valueChanges = control.valueChanges.pipe(debounceTime(debounce.default));
1003
- }
1004
- const sub = valueChanges.subscribe((value) => {
1005
- var _a;
1006
- // workaround for https://github.com/angular/angular/issues/13792
1007
- if (((_a = control._fields) === null || _a === void 0 ? void 0 : _a.length) > 1 && control instanceof FormControl) {
1008
- control.patchValue(value, { emitEvent: false, onlySelf: true });
1009
- }
1010
- if (hasKey(field)) {
1011
- assignFieldValue(field, value);
1012
- }
1013
- field.options.fieldChanges.next({ value, field, type: 'valueChanges' });
1014
- });
1015
- subscribes.push(() => sub.unsubscribe());
1016
- }
1017
- let templateFieldsSubs = [];
1018
- observe(field, ['_localFields'], ({ currentValue }) => {
1019
- templateFieldsSubs.forEach((unsubscribe) => unsubscribe());
1020
- templateFieldsSubs = (currentValue || []).map((f) => this.fieldChanges(f));
1021
- });
1022
- return () => {
1023
- subscribes.forEach((unsubscribe) => unsubscribe());
1024
- templateFieldsSubs.forEach((unsubscribe) => unsubscribe());
1025
- };
1026
- }
1027
- }
1028
- FormlyField.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyField, deps: [{ token: FormlyConfig }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: FormlyFieldTemplates, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1029
- FormlyField.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: FormlyField, selector: "formly-field", inputs: { field: "field" }, viewQueries: [{ propertyName: "viewContainerRef", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: '<ng-template #container></ng-template>', isInline: true, styles: [":host:empty{display:none}\n"] });
1030
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyField, decorators: [{
1031
- type: Component,
1032
- args: [{ selector: 'formly-field', template: '<ng-template #container></ng-template>', styles: [":host:empty{display:none}\n"] }]
1033
- }], ctorParameters: function () {
1034
- return [{ type: FormlyConfig }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: FormlyFieldTemplates, decorators: [{
1035
- type: Optional
1036
- }] }];
1037
- }, propDecorators: { field: [{
1038
- type: Input
1039
- }], viewContainerRef: [{
1040
- type: ViewChild,
1041
- args: ['container', { read: ViewContainerRef, static: true }]
1042
- }] } });
1043
-
1044
- /**
1045
- * The `<form-form>` component is the main container of the form,
1046
- * which takes care of managing the form state
1047
- * and delegates the rendering of each field to `<formly-field>` component.
1048
- */
1049
- class FormlyForm {
1050
- constructor(builder, config, ngZone, fieldTemplates) {
1051
- this.builder = builder;
1052
- this.config = config;
1053
- this.ngZone = ngZone;
1054
- this.fieldTemplates = fieldTemplates;
1055
- /** Event that is emitted when the model value is changed */
1056
- this.modelChange = new EventEmitter();
1057
- this.field = { type: 'formly-group' };
1058
- this._modelChangeValue = {};
1059
- this.valueChangesUnsubscribe = () => { };
1060
- }
1061
- /** The form instance which allow to track model value and validation status. */
1062
- set form(form) {
1063
- this.field.form = form;
1064
- }
1065
- get form() {
1066
- return this.field.form;
1067
- }
1068
- /** The model to be represented by the form. */
1069
- set model(model) {
1070
- if (this.config.extras.immutable && this._modelChangeValue === model) {
1071
- return;
1072
- }
1073
- this.setField({ model });
1074
- }
1075
- get model() {
1076
- return this.field.model;
1077
- }
1078
- /** The field configurations for building the form. */
1079
- set fields(fieldGroup) {
1080
- this.setField({ fieldGroup });
1081
- }
1082
- get fields() {
1083
- return this.field.fieldGroup;
1084
- }
1085
- /** Options for the form. */
1086
- set options(options) {
1087
- this.setField({ options });
1088
- }
1089
- get options() {
1090
- return this.field.options;
1091
- }
1092
- set templates(templates) {
1093
- this.fieldTemplates.templates = templates;
1094
- }
1095
- ngDoCheck() {
1096
- if (this.config.extras.checkExpressionOn === 'changeDetectionCheck') {
1097
- this.checkExpressionChange();
1098
- }
1099
- }
1100
- ngOnChanges(changes) {
1101
- if (changes.fields && this.form) {
1102
- clearControl(this.form);
1103
- }
1104
- if (changes.fields || changes.form || (changes.model && this._modelChangeValue !== changes.model.currentValue)) {
1105
- this.valueChangesUnsubscribe();
1106
- this.builder.build(this.field);
1107
- this.valueChangesUnsubscribe = this.valueChanges();
1108
- }
1109
- }
1110
- ngOnDestroy() {
1111
- this.valueChangesUnsubscribe();
1112
- }
1113
- checkExpressionChange() {
1114
- var _a, _b;
1115
- (_b = (_a = this.field.options).checkExpressions) === null || _b === void 0 ? void 0 : _b.call(_a, this.field);
1116
- }
1117
- valueChanges() {
1118
- var _a, _b;
1119
- this.valueChangesUnsubscribe();
1120
- let formEvents = null;
1121
- if (isSignalRequired()) {
1122
- let submitted = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.parentForm) === null || _b === void 0 ? void 0 : _b.submitted;
1123
- formEvents = this.form.events.subscribe(() => {
1124
- var _a, _b, _c, _d;
1125
- if (submitted !== ((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.parentForm) === null || _b === void 0 ? void 0 : _b.submitted)) {
1126
- this.options.detectChanges(this.field);
1127
- submitted = (_d = (_c = this.options) === null || _c === void 0 ? void 0 : _c.parentForm) === null || _d === void 0 ? void 0 : _d.submitted;
1128
- }
1129
- });
1130
- }
1131
- let fieldChangesDetection = [];
1132
- const valueChanges = this.field.options.fieldChanges
1133
- .pipe(filter(({ field, type }) => hasKey(field) && type === 'valueChanges'), switchMap(() => (isNoopNgZone(this.ngZone) ? of(null) : this.ngZone.onStable.asObservable().pipe(take(1)))))
1134
- .subscribe(() => this.ngZone.runGuarded(() => {
1135
- // runGuarded is used to keep in sync the expression changes
1136
- // https://github.com/ngx-formly/ngx-formly/issues/2095
1137
- this.checkExpressionChange();
1138
- if (this.field.options) {
1139
- fieldChangesDetection.push(observeDeep(this.field.options, ['formState'], () => this.field.options.detectChanges(this.field)));
1140
- }
1141
- this.modelChange.emit((this._modelChangeValue = clone(this.model)));
1142
- }));
1143
- return () => {
1144
- fieldChangesDetection.forEach((fnc) => fnc());
1145
- formEvents === null || formEvents === void 0 ? void 0 : formEvents.unsubscribe();
1146
- valueChanges.unsubscribe();
1147
- };
1148
- }
1149
- setField(field) {
1150
- if (this.config.extras.immutable) {
1151
- this.field = Object.assign(Object.assign({}, this.field), clone(field));
1152
- }
1153
- else {
1154
- Object.keys(field).forEach((p) => (this.field[p] = field[p]));
1155
- }
1156
- }
1157
- }
1158
- FormlyForm.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyForm, deps: [{ token: FormlyFormBuilder }, { token: FormlyConfig }, { token: i0.NgZone }, { token: FormlyFieldTemplates }], target: i0.ɵɵFactoryTarget.Component });
1159
- FormlyForm.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: FormlyForm, selector: "formly-form", inputs: { form: "form", model: "model", fields: "fields", options: "options" }, outputs: { modelChange: "modelChange" }, providers: [FormlyFormBuilder, FormlyFieldTemplates], queries: [{ propertyName: "templates", predicate: FormlyTemplate }], usesOnChanges: true, ngImport: i0, template: '<formly-field [field]="field"></formly-field>', isInline: true, components: [{ type: FormlyField, selector: "formly-field", inputs: ["field"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1160
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyForm, decorators: [{
1161
- type: Component,
1162
- args: [{
1163
- selector: 'formly-form',
1164
- template: '<formly-field [field]="field"></formly-field>',
1165
- providers: [FormlyFormBuilder, FormlyFieldTemplates],
1166
- changeDetection: ChangeDetectionStrategy.OnPush,
1167
- }]
1168
- }], ctorParameters: function () { return [{ type: FormlyFormBuilder }, { type: FormlyConfig }, { type: i0.NgZone }, { type: FormlyFieldTemplates }]; }, propDecorators: { form: [{
1169
- type: Input
1170
- }], model: [{
1171
- type: Input
1172
- }], fields: [{
1173
- type: Input
1174
- }], options: [{
1175
- type: Input
1176
- }], modelChange: [{
1177
- type: Output
1178
- }], templates: [{
1179
- type: ContentChildren,
1180
- args: [FormlyTemplate]
1181
- }] } });
1182
-
1183
- /**
1184
- * Allow to link the `field` HTML attributes (`id`, `name` ...) and Event attributes (`focus`, `blur` ...) to an element in the DOM.
1185
- */
1186
- class FormlyAttributes {
1187
- constructor(renderer, elementRef, _document) {
1188
- this.renderer = renderer;
1189
- this.elementRef = elementRef;
1190
- this.uiAttributesCache = {};
1191
- /**
1192
- * HostBinding doesn't register listeners conditionally which may produce some perf issues.
1193
- *
1194
- * Formly issue: https://github.com/ngx-formly/ngx-formly/issues/1991
1195
- */
1196
- this.uiEvents = {
1197
- listeners: [],
1198
- events: ['click', 'keyup', 'keydown', 'keypress', 'focus', 'blur', 'change'],
1199
- callback: (eventName, $event) => {
1200
- switch (eventName) {
1201
- case 'focus':
1202
- return this.onFocus($event);
1203
- case 'blur':
1204
- return this.onBlur($event);
1205
- case 'change':
1206
- return this.onChange($event);
1207
- default:
1208
- return this.props[eventName](this.field, $event);
1209
- }
1210
- },
1211
- };
1212
- this.document = _document;
1213
- }
1214
- get props() {
1215
- return this.field.props || {};
1216
- }
1217
- get fieldAttrElements() {
1218
- var _a;
1219
- return ((_a = this.field) === null || _a === void 0 ? void 0 : _a['_elementRefs']) || [];
1220
- }
1221
- ngOnChanges(changes) {
1222
- var _a;
1223
- if (changes.field) {
1224
- this.field.name && this.setAttribute('name', this.field.name);
1225
- this.uiEvents.listeners.forEach((listener) => listener());
1226
- this.uiEvents.events.forEach((eventName) => {
1227
- var _a;
1228
- if (((_a = this.props) === null || _a === void 0 ? void 0 : _a[eventName]) || ['focus', 'blur', 'change'].indexOf(eventName) !== -1) {
1229
- this.uiEvents.listeners.push(this.renderer.listen(this.elementRef.nativeElement, eventName, (e) => this.uiEvents.callback(eventName, e)));
1230
- }
1231
- });
1232
- if ((_a = this.props) === null || _a === void 0 ? void 0 : _a.attributes) {
1233
- observe(this.field, ['props', 'attributes'], ({ currentValue, previousValue }) => {
1234
- if (previousValue) {
1235
- Object.keys(previousValue).forEach((attr) => this.removeAttribute(attr));
1236
- }
1237
- if (currentValue) {
1238
- Object.keys(currentValue).forEach((attr) => {
1239
- if (currentValue[attr] != null) {
1240
- this.setAttribute(attr, currentValue[attr]);
1241
- }
1242
- });
1243
- }
1244
- });
1245
- }
1246
- this.detachElementRef(changes.field.previousValue);
1247
- this.attachElementRef(changes.field.currentValue);
1248
- if (this.fieldAttrElements.length === 1) {
1249
- !this.id && this.field.id && this.setAttribute('id', this.field.id);
1250
- this.focusObserver = observe(this.field, ['focus'], ({ currentValue }) => {
1251
- this.toggleFocus(currentValue);
1252
- });
1253
- }
1254
- }
1255
- if (changes.id) {
1256
- this.setAttribute('id', this.id);
1257
- }
1258
- }
1259
- /**
1260
- * We need to re-evaluate all the attributes on every change detection cycle, because
1261
- * by using a HostBinding we run into certain edge cases. This means that whatever logic
1262
- * is in here has to be super lean or we risk seriously damaging or destroying the performance.
1263
- *
1264
- * Formly issue: https://github.com/ngx-formly/ngx-formly/issues/1317
1265
- * Material issue: https://github.com/angular/components/issues/14024
1266
- */
1267
- ngDoCheck() {
1268
- if (!this.uiAttributes) {
1269
- const element = this.elementRef.nativeElement;
1270
- this.uiAttributes = [...FORMLY_VALIDATORS, 'tabindex', 'placeholder', 'readonly', 'disabled', 'step'].filter((attr) => !element.hasAttribute || !element.hasAttribute(attr));
1271
- }
1272
- for (let i = 0; i < this.uiAttributes.length; i++) {
1273
- const attr = this.uiAttributes[i];
1274
- const value = this.props[attr];
1275
- if (this.uiAttributesCache[attr] !== value &&
1276
- (!this.props.attributes || !this.props.attributes.hasOwnProperty(attr.toLowerCase()))) {
1277
- this.uiAttributesCache[attr] = value;
1278
- if (value || value === 0) {
1279
- this.setAttribute(attr, value === true ? attr : `${value}`);
1280
- }
1281
- else {
1282
- this.removeAttribute(attr);
1283
- }
1284
- }
1285
- }
1286
- }
1287
- ngOnDestroy() {
1288
- var _a;
1289
- this.uiEvents.listeners.forEach((listener) => listener());
1290
- this.detachElementRef(this.field);
1291
- (_a = this.focusObserver) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1292
- }
1293
- toggleFocus(value) {
1294
- const element = this.fieldAttrElements ? this.fieldAttrElements[0] : null;
1295
- if (!element || !element.nativeElement.focus) {
1296
- return;
1297
- }
1298
- const isFocused = !!this.document.activeElement &&
1299
- this.fieldAttrElements.some(({ nativeElement }) => this.document.activeElement === nativeElement || nativeElement.contains(this.document.activeElement));
1300
- if (value && !isFocused) {
1301
- Promise.resolve().then(() => element.nativeElement.focus());
1302
- }
1303
- else if (!value && isFocused) {
1304
- Promise.resolve().then(() => element.nativeElement.blur());
1305
- }
1306
- }
1307
- onFocus($event) {
1308
- var _a, _b, _c;
1309
- (_a = this.focusObserver) === null || _a === void 0 ? void 0 : _a.setValue(true);
1310
- (_c = (_b = this.props).focus) === null || _c === void 0 ? void 0 : _c.call(_b, this.field, $event);
1311
- }
1312
- onBlur($event) {
1313
- var _a, _b, _c;
1314
- (_a = this.focusObserver) === null || _a === void 0 ? void 0 : _a.setValue(false);
1315
- (_c = (_b = this.props).blur) === null || _c === void 0 ? void 0 : _c.call(_b, this.field, $event);
1316
- }
1317
- // handle custom `change` event, for regular ones rely on DOM listener
1318
- onHostChange($event) {
1319
- if ($event instanceof Event) {
1320
- return;
1321
- }
1322
- this.onChange($event);
1323
- }
1324
- onChange($event) {
1325
- var _a, _b, _c;
1326
- (_b = (_a = this.props).change) === null || _b === void 0 ? void 0 : _b.call(_a, this.field, $event);
1327
- (_c = this.field.formControl) === null || _c === void 0 ? void 0 : _c.markAsDirty();
1328
- }
1329
- attachElementRef(f) {
1330
- var _a;
1331
- if (!f) {
1332
- return;
1333
- }
1334
- if (((_a = f['_elementRefs']) === null || _a === void 0 ? void 0 : _a.indexOf(this.elementRef)) === -1) {
1335
- f['_elementRefs'].push(this.elementRef);
1336
- }
1337
- else {
1338
- defineHiddenProp(f, '_elementRefs', [this.elementRef]);
1339
- }
1340
- }
1341
- detachElementRef(f) {
1342
- const index = (f === null || f === void 0 ? void 0 : f['_elementRefs']) ? this.fieldAttrElements.indexOf(this.elementRef) : -1;
1343
- if (index !== -1) {
1344
- f['_elementRefs'].splice(index, 1);
1345
- }
1346
- }
1347
- setAttribute(attr, value) {
1348
- this.renderer.setAttribute(this.elementRef.nativeElement, attr, value);
1349
- }
1350
- removeAttribute(attr) {
1351
- this.renderer.removeAttribute(this.elementRef.nativeElement, attr);
1352
- }
1353
- }
1354
- FormlyAttributes.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyAttributes, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
1355
- FormlyAttributes.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: FormlyAttributes, selector: "[formlyAttributes]", inputs: { field: ["formlyAttributes", "field"], id: "id" }, host: { listeners: { "change": "onHostChange($event)" } }, usesOnChanges: true, ngImport: i0 });
1356
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyAttributes, decorators: [{
1357
- type: Directive,
1358
- args: [{
1359
- selector: '[formlyAttributes]',
1360
- host: {
1361
- '(change)': 'onHostChange($event)',
1362
- },
1363
- }]
1364
- }], ctorParameters: function () {
1365
- return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: undefined, decorators: [{
1366
- type: Inject,
1367
- args: [DOCUMENT]
1368
- }] }];
1369
- }, propDecorators: { field: [{
1370
- type: Input,
1371
- args: ['formlyAttributes']
1372
- }], id: [{
1373
- type: Input
1374
- }] } });
1375
-
1376
- class FieldType {
1377
- constructor() {
1378
- this.field = {};
1379
- }
1380
- set _formlyControls(controls) {
1381
- const f = this.field;
1382
- f._localFields = controls
1383
- .map((c) => c.control._fields || [])
1384
- .flat()
1385
- .filter((f) => f.formControl !== this.field.formControl);
1386
- }
1387
- get model() {
1388
- return this.field.model;
1389
- }
1390
- get form() {
1391
- return this.field.form;
1392
- }
1393
- get options() {
1394
- return this.field.options;
1395
- }
1396
- get key() {
1397
- return this.field.key;
1398
- }
1399
- get formControl() {
1400
- return this.field.formControl;
1401
- }
1402
- get props() {
1403
- return (this.field.props || {});
1404
- }
1405
- /** @deprecated Use `props` instead. */
1406
- get to() {
1407
- return this.props;
1408
- }
1409
- get showError() {
1410
- return this.options.showError(this);
1411
- }
1412
- get id() {
1413
- return this.field.id;
1414
- }
1415
- get formState() {
1416
- var _a;
1417
- return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.formState) || {};
1418
- }
1419
- }
1420
- FieldType.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FieldType, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1421
- FieldType.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: FieldType, inputs: { field: "field" }, viewQueries: [{ propertyName: "_formlyControls", predicate: NgControl, descendants: true }], ngImport: i0 });
1422
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FieldType, decorators: [{
1423
- type: Directive
1424
- }], propDecorators: { _formlyControls: [{
1425
- type: ViewChildren,
1426
- args: [NgControl]
1427
- }], field: [{
1428
- type: Input
1429
- }] } });
1430
-
1431
- /** @ignore */
1432
- class FormlyGroup extends FieldType {
1433
- }
1434
- FormlyGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyGroup, deps: null, target: i0.ɵɵFactoryTarget.Component });
1435
- FormlyGroup.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: FormlyGroup, selector: "formly-group", host: { properties: { "class": "field.fieldGroupClassName || \"\"" } }, usesInheritance: true, ngImport: i0, template: `
1436
- <formly-field *ngFor="let f of field.fieldGroup" [field]="f"></formly-field>
1437
- <ng-content></ng-content>
1438
- `, isInline: true, components: [{ type: FormlyField, selector: "formly-field", inputs: ["field"] }], directives: [{ type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1439
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyGroup, decorators: [{
1440
- type: Component,
1441
- args: [{
1442
- selector: 'formly-group',
1443
- template: `
1444
- <formly-field *ngFor="let f of field.fieldGroup" [field]="f"></formly-field>
1445
- <ng-content></ng-content>
1446
- `,
1447
- host: {
1448
- '[class]': 'field.fieldGroupClassName || ""',
1449
- },
1450
- changeDetection: ChangeDetectionStrategy.OnPush,
1451
- }]
1452
- }] });
1453
-
1454
- /**
1455
- * The `<formly-validation-message>` component renders the error message of a given `field`.
1456
- */
1457
- class FormlyValidationMessage {
1458
- constructor(config) {
1459
- this.config = config;
1460
- }
1461
- ngOnChanges() {
1462
- const EXPR_VALIDATORS = FORMLY_VALIDATORS.map((v) => `templateOptions.${v}`);
1463
- this.errorMessage$ = merge(this.field.formControl.statusChanges, !this.field.options
1464
- ? of(null)
1465
- : this.field.options.fieldChanges.pipe(filter(({ field, type, property }) => {
1466
- return (field === this.field &&
1467
- type === 'expressionChanges' &&
1468
- (property.indexOf('validation') !== -1 || EXPR_VALIDATORS.indexOf(property) !== -1));
1469
- }))).pipe(startWith(null), switchMap(() => (isObservable(this.errorMessage) ? this.errorMessage : of(this.errorMessage))));
1470
- }
1471
- get errorMessage() {
1472
- var _a, _b, _c, _d, _e, _f;
1473
- const fieldForm = this.field.formControl;
1474
- for (const error in fieldForm.errors) {
1475
- if (fieldForm.errors.hasOwnProperty(error)) {
1476
- let message = this.config.getValidatorMessage(error);
1477
- if (isObject(fieldForm.errors[error])) {
1478
- if (fieldForm.errors[error].errorPath) {
1479
- return undefined;
1480
- }
1481
- if (fieldForm.errors[error].message) {
1482
- message = fieldForm.errors[error].message;
1483
- }
1484
- }
1485
- if ((_b = (_a = this.field.validation) === null || _a === void 0 ? void 0 : _a.messages) === null || _b === void 0 ? void 0 : _b[error]) {
1486
- message = this.field.validation.messages[error];
1487
- }
1488
- if ((_d = (_c = this.field.validators) === null || _c === void 0 ? void 0 : _c[error]) === null || _d === void 0 ? void 0 : _d.message) {
1489
- message = this.field.validators[error].message;
1490
- }
1491
- if ((_f = (_e = this.field.asyncValidators) === null || _e === void 0 ? void 0 : _e[error]) === null || _f === void 0 ? void 0 : _f.message) {
1492
- message = this.field.asyncValidators[error].message;
1493
- }
1494
- if (typeof message === 'function') {
1495
- return message(fieldForm.errors[error], this.field);
1496
- }
1497
- return message;
1498
- }
1499
- }
1500
- return undefined;
1501
- }
1502
- }
1503
- FormlyValidationMessage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyValidationMessage, deps: [{ token: FormlyConfig }], target: i0.ɵɵFactoryTarget.Component });
1504
- FormlyValidationMessage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: FormlyValidationMessage, selector: "formly-validation-message", inputs: { field: "field" }, usesOnChanges: true, ngImport: i0, template: '{{ errorMessage$ | async }}', isInline: true, pipes: { "async": i2$1.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1505
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyValidationMessage, decorators: [{
1506
- type: Component,
1507
- args: [{
1508
- selector: 'formly-validation-message',
1509
- template: '{{ errorMessage$ | async }}',
1510
- changeDetection: ChangeDetectionStrategy.OnPush,
1511
- }]
1512
- }], ctorParameters: function () { return [{ type: FormlyConfig }]; }, propDecorators: { field: [{
1513
- type: Input
1514
- }] } });
1515
-
1516
- class FieldArrayType extends FieldType {
1517
- onPopulate(field) {
1518
- if (hasKey(field)) {
1519
- const control = findControl(field);
1520
- registerControl(field, control ? control : new FormArray([], { updateOn: field.modelOptions.updateOn }));
1521
- }
1522
- field.fieldGroup = field.fieldGroup || [];
1523
- const length = Array.isArray(field.model) ? field.model.length : 0;
1524
- if (field.fieldGroup.length > length) {
1525
- for (let i = field.fieldGroup.length - 1; i >= length; --i) {
1526
- unregisterControl(field.fieldGroup[i], true);
1527
- field.fieldGroup.splice(i, 1);
1528
- }
1529
- }
1530
- for (let i = field.fieldGroup.length; i < length; i++) {
1531
- const f = Object.assign({}, clone(typeof field.fieldArray === 'function' ? field.fieldArray(field) : field.fieldArray));
1532
- if (f.key !== null) {
1533
- f.key = `${i}`;
1534
- }
1535
- field.fieldGroup.push(f);
1536
- }
1537
- }
1538
- add(i, initialModel, { markAsDirty } = { markAsDirty: true }) {
1539
- markAsDirty && this.formControl.markAsDirty();
1540
- i = i == null ? this.field.fieldGroup.length : i;
1541
- if (!this.model) {
1542
- assignFieldValue(this.field, []);
1543
- }
1544
- this.model.splice(i, 0, initialModel ? clone(initialModel) : undefined);
1545
- this.markFieldForCheck(this.field.fieldGroup[i]);
1546
- this._build();
1547
- }
1548
- remove(i, { markAsDirty } = { markAsDirty: true }) {
1549
- markAsDirty && this.formControl.markAsDirty();
1550
- this.model.splice(i, 1);
1551
- const field = this.field.fieldGroup[i];
1552
- this.field.fieldGroup.splice(i, 1);
1553
- this.field.fieldGroup.forEach((f, key) => this.updateArrayElementKey(f, `${key}`));
1554
- unregisterControl(field, true);
1555
- this._build();
1556
- }
1557
- _build() {
1558
- var _a;
1559
- const fields = (_a = this.field.formControl._fields) !== null && _a !== void 0 ? _a : [this.field];
1560
- fields.forEach((f) => this.options.build(f));
1561
- this.options.fieldChanges.next({
1562
- field: this.field,
1563
- value: getFieldValue(this.field),
1564
- type: 'valueChanges',
1565
- });
1566
- }
1567
- updateArrayElementKey(f, newKey) {
1568
- var _a;
1569
- if (hasKey(f)) {
1570
- f.key = newKey;
1571
- return;
1572
- }
1573
- if (!((_a = f.fieldGroup) === null || _a === void 0 ? void 0 : _a.length)) {
1574
- return;
1575
- }
1576
- for (let i = 0; i < f.fieldGroup.length; i++) {
1577
- this.updateArrayElementKey(f.fieldGroup[i], newKey);
1578
- }
1579
- }
1580
- markFieldForCheck(f) {
1581
- var _a;
1582
- if (!f) {
1583
- return;
1584
- }
1585
- (_a = f.fieldGroup) === null || _a === void 0 ? void 0 : _a.forEach((c) => this.markFieldForCheck(c));
1586
- if (f.hide === false) {
1587
- this.options._hiddenFieldsForCheck.push({ field: f });
1588
- }
1589
- }
1590
- }
1591
- FieldArrayType.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FieldArrayType, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1592
- FieldArrayType.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: FieldArrayType, usesInheritance: true, ngImport: i0 });
1593
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FieldArrayType, decorators: [{
1594
- type: Directive
1595
- }] });
1596
-
1597
- class FieldWrapper extends FieldType {
1598
- set _formlyControls(_) { }
1599
- set _staticContent(content) {
1600
- this.fieldComponent = content;
1601
- }
1602
- }
1603
- FieldWrapper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FieldWrapper, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1604
- FieldWrapper.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.12", type: FieldWrapper, viewQueries: [{ propertyName: "fieldComponent", first: true, predicate: ["fieldComponent"], descendants: true, read: ViewContainerRef }, { propertyName: "_staticContent", first: true, predicate: ["fieldComponent"], descendants: true, read: ViewContainerRef, static: true }], usesInheritance: true, ngImport: i0 });
1605
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FieldWrapper, decorators: [{
1606
- type: Directive
1607
- }], propDecorators: { fieldComponent: [{
1608
- type: ViewChild,
1609
- args: ['fieldComponent', { read: ViewContainerRef }]
1610
- }], _staticContent: [{
1611
- type: ViewChild,
1612
- args: ['fieldComponent', { read: ViewContainerRef, static: true }]
1613
- }] } });
1614
-
1615
- /** @ignore */
1616
- class FormlyTemplateType extends FieldType {
1617
- constructor(sanitizer) {
1618
- super();
1619
- this.sanitizer = sanitizer;
1620
- this.innerHtml = {};
1621
- }
1622
- get template() {
1623
- if (this.field && this.field.template !== this.innerHtml.template) {
1624
- this.innerHtml = {
1625
- template: this.field.template,
1626
- content: this.props.safeHtml
1627
- ? this.sanitizer.bypassSecurityTrustHtml(this.field.template)
1628
- : this.field.template,
1629
- };
1630
- }
1631
- return this.innerHtml.content;
1632
- }
1633
- }
1634
- FormlyTemplateType.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyTemplateType, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
1635
- FormlyTemplateType.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: FormlyTemplateType, selector: "formly-template", usesInheritance: true, ngImport: i0, template: `<div [innerHtml]="template"></div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1636
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyTemplateType, decorators: [{
1637
- type: Component,
1638
- args: [{
1639
- selector: 'formly-template',
1640
- template: `<div [innerHtml]="template"></div>`,
1641
- changeDetection: ChangeDetectionStrategy.OnPush,
1642
- }]
1643
- }], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
1644
-
1645
- function evalStringExpression(expression, argNames) {
1646
- try {
1647
- return Function(...argNames, `return ${expression};`);
1648
- }
1649
- catch (error) {
1650
- console.error(error);
1651
- }
1652
- }
1653
- function evalExpression(expression, thisArg, argVal) {
1654
- if (typeof expression === 'function') {
1655
- return expression.apply(thisArg, argVal);
1656
- }
1657
- else {
1658
- return expression ? true : false;
1659
- }
1660
- }
1661
-
1662
- class FieldExpressionExtension {
1663
- onPopulate(field) {
1664
- if (field._expressions) {
1665
- return;
1666
- }
1667
- // cache built expression
1668
- defineHiddenProp(field, '_expressions', {});
1669
- observe(field, ['hide'], ({ currentValue, firstChange }) => {
1670
- defineHiddenProp(field, '_hide', !!currentValue);
1671
- if (!firstChange || (firstChange && currentValue === true)) {
1672
- field.props.hidden = currentValue;
1673
- field.options._hiddenFieldsForCheck.push({ field });
1674
- }
1675
- });
1676
- if (field.hideExpression) {
1677
- observe(field, ['hideExpression'], ({ currentValue: expr }) => {
1678
- field._expressions.hide = this.parseExpressions(field, 'hide', typeof expr === 'boolean' ? () => expr : expr);
1679
- });
1680
- }
1681
- const evalExpr = (key, expr) => {
1682
- if (typeof expr === 'string' || isFunction(expr)) {
1683
- field._expressions[key] = this.parseExpressions(field, key, expr);
1684
- }
1685
- else if (expr instanceof Observable) {
1686
- field._expressions[key] = {
1687
- value$: expr.pipe(tap((v) => {
1688
- this.evalExpr(field, key, v);
1689
- field.options._detectChanges(field);
1690
- })),
1691
- };
1692
- }
1693
- };
1694
- field.expressions = field.expressions || {};
1695
- for (const key of Object.keys(field.expressions)) {
1696
- observe(field, ['expressions', key], ({ currentValue: expr }) => {
1697
- evalExpr(key, isFunction(expr) ? (...args) => expr(field, args[3]) : expr);
1698
- });
1699
- }
1700
- field.expressionProperties = field.expressionProperties || {};
1701
- for (const key of Object.keys(field.expressionProperties)) {
1702
- observe(field, ['expressionProperties', key], ({ currentValue }) => evalExpr(key, currentValue));
1703
- }
1704
- }
1705
- postPopulate(field) {
1706
- if (field.parent) {
1707
- return;
1708
- }
1709
- if (!field.options.checkExpressions) {
1710
- let checkLocked = false;
1711
- field.options.checkExpressions = (f, ignoreCache) => {
1712
- if (checkLocked) {
1713
- return;
1714
- }
1715
- checkLocked = true;
1716
- const fieldChanged = this.checkExpressions(f, ignoreCache);
1717
- const options = field.options;
1718
- options._hiddenFieldsForCheck
1719
- .sort((f) => (f.field.hide ? -1 : 1))
1720
- .forEach((f) => { var _a; return this.changeHideState(f.field, (_a = f.field.hide) !== null && _a !== void 0 ? _a : f.default, !ignoreCache); });
1721
- options._hiddenFieldsForCheck = [];
1722
- if (fieldChanged) {
1723
- this.checkExpressions(field);
1724
- }
1725
- checkLocked = false;
1726
- };
1727
- field.options._checkField = (f, ignoreCache) => {
1728
- console.warn(`Formly: 'options._checkField' is deprecated since v6.0, use 'options.checkExpressions' instead.`);
1729
- field.options.checkExpressions(f, ignoreCache);
1730
- };
1731
- }
1732
- }
1733
- parseExpressions(field, path, expr) {
1734
- let parentExpression;
1735
- if (field.parent && ['hide', 'props.disabled'].includes(path)) {
1736
- const rootValue = (f) => {
1737
- return path === 'hide' ? f.hide : f.props.disabled;
1738
- };
1739
- parentExpression = () => {
1740
- let root = field.parent;
1741
- while (root.parent && !rootValue(root)) {
1742
- root = root.parent;
1743
- }
1744
- return rootValue(root);
1745
- };
1746
- }
1747
- expr = expr || (() => false);
1748
- if (typeof expr === 'string') {
1749
- expr = evalStringExpression(expr, ['model', 'formState', 'field']);
1750
- }
1751
- let currentValue;
1752
- return {
1753
- callback: (ignoreCache) => {
1754
- try {
1755
- const exprValue = evalExpression(parentExpression ? (...args) => parentExpression(field) || expr(...args) : expr, { field }, [field.model, field.options.formState, field, ignoreCache]);
1756
- if (ignoreCache ||
1757
- (currentValue !== exprValue &&
1758
- (!isObject(exprValue) ||
1759
- isObservable(exprValue) ||
1760
- JSON.stringify(exprValue) !== JSON.stringify(currentValue)))) {
1761
- currentValue = exprValue;
1762
- this.evalExpr(field, path, exprValue);
1763
- return true;
1764
- }
1765
- return false;
1766
- }
1767
- catch (error) {
1768
- error.message = `[Formly Error] [Expression "${path}"] ${error.message}`;
1769
- throw error;
1770
- }
1771
- },
1772
- };
1773
- }
1774
- checkExpressions(field, ignoreCache = false) {
1775
- var _a, _b, _c;
1776
- if (!field) {
1777
- return false;
1778
- }
1779
- let fieldChanged = false;
1780
- if (field._expressions) {
1781
- for (const key of Object.keys(field._expressions)) {
1782
- ((_b = (_a = field._expressions[key]).callback) === null || _b === void 0 ? void 0 : _b.call(_a, ignoreCache)) && (fieldChanged = true);
1783
- }
1784
- }
1785
- (_c = field.fieldGroup) === null || _c === void 0 ? void 0 : _c.forEach((f) => this.checkExpressions(f, ignoreCache) && (fieldChanged = true));
1786
- return fieldChanged;
1787
- }
1788
- changeDisabledState(field, value) {
1789
- if (field.fieldGroup) {
1790
- field.fieldGroup
1791
- .filter((f) => !f._expressions.hasOwnProperty('props.disabled'))
1792
- .forEach((f) => this.changeDisabledState(f, value));
1793
- }
1794
- if (hasKey(field) && field.props.disabled !== value) {
1795
- field.props.disabled = value;
1796
- }
1797
- }
1798
- changeHideState(field, hide, resetOnHide) {
1799
- var _a, _b, _c;
1800
- if (field.fieldGroup) {
1801
- field.fieldGroup
1802
- .filter((f) => f && !f._expressions.hide)
1803
- .forEach((f) => this.changeHideState(f, hide, resetOnHide));
1804
- }
1805
- if (field.formControl && hasKey(field)) {
1806
- defineHiddenProp(field, '_hide', !!(hide || field.hide));
1807
- const c = field.formControl;
1808
- if (((_a = c._fields) === null || _a === void 0 ? void 0 : _a.length) > 1) {
1809
- updateValidity(c);
1810
- }
1811
- if (hide === true && (!c._fields || c._fields.every((f) => !!f._hide))) {
1812
- unregisterControl(field, true);
1813
- if (resetOnHide && field.resetOnHide) {
1814
- assignFieldValue(field, undefined);
1815
- field.formControl.reset({ value: undefined, disabled: field.formControl.disabled });
1816
- field.options.fieldChanges.next({ value: undefined, field, type: 'valueChanges' });
1817
- if (field.fieldGroup && field.formControl instanceof FormArray) {
1818
- field.fieldGroup.length = 0;
1819
- }
1820
- }
1821
- }
1822
- else if (hide === false) {
1823
- if (field.resetOnHide && !isUndefined(field.defaultValue) && isUndefined(getFieldValue(field))) {
1824
- assignFieldValue(field, field.defaultValue);
1825
- }
1826
- registerControl(field, undefined, true);
1827
- if (field.resetOnHide && field.fieldArray && ((_b = field.fieldGroup) === null || _b === void 0 ? void 0 : _b.length) !== ((_c = field.model) === null || _c === void 0 ? void 0 : _c.length)) {
1828
- field.options.build(field);
1829
- }
1830
- }
1831
- }
1832
- if (field.options.fieldChanges) {
1833
- field.options.fieldChanges.next({ field, type: 'hidden', value: hide });
1834
- }
1835
- }
1836
- evalExpr(field, prop, value) {
1837
- if (prop.indexOf('model.') === 0) {
1838
- const key = prop.replace(/^model\./, ''), parent = field.fieldGroup ? field : field.parent;
1839
- let control = (field === null || field === void 0 ? void 0 : field.key) === key ? field.formControl : field.form.get(key);
1840
- if (!control && field.get(key)) {
1841
- control = field.get(key).formControl;
1842
- }
1843
- assignFieldValue({ key, parent, model: field.model }, value);
1844
- if (control && !(isNil(control.value) && isNil(value)) && control.value !== value) {
1845
- control.patchValue(value);
1846
- }
1847
- }
1848
- else {
1849
- try {
1850
- let target = field;
1851
- const paths = this._evalExpressionPath(field, prop);
1852
- const lastIndex = paths.length - 1;
1853
- for (let i = 0; i < lastIndex; i++) {
1854
- target = target[paths[i]];
1855
- }
1856
- target[paths[lastIndex]] = value;
1857
- }
1858
- catch (error) {
1859
- error.message = `[Formly Error] [Expression "${prop}"] ${error.message}`;
1860
- throw error;
1861
- }
1862
- if (['templateOptions.disabled', 'props.disabled'].includes(prop) && hasKey(field)) {
1863
- this.changeDisabledState(field, value);
1864
- }
1865
- }
1866
- this.emitExpressionChanges(field, prop, value);
1867
- }
1868
- emitExpressionChanges(field, property, value) {
1869
- if (!field.options.fieldChanges) {
1870
- return;
1871
- }
1872
- field.options.fieldChanges.next({
1873
- field,
1874
- type: 'expressionChanges',
1875
- property,
1876
- value,
1877
- });
1878
- }
1879
- _evalExpressionPath(field, prop) {
1880
- if (field._expressions[prop] && field._expressions[prop].paths) {
1881
- return field._expressions[prop].paths;
1882
- }
1883
- let paths = [];
1884
- if (prop.indexOf('[') === -1) {
1885
- paths = prop.split('.');
1886
- }
1887
- else {
1888
- prop
1889
- .split(/[[\]]{1,2}/) // https://stackoverflow.com/a/20198206
1890
- .filter((p) => p)
1891
- .forEach((path) => {
1892
- const arrayPath = path.match(/['|"](.*?)['|"]/);
1893
- if (arrayPath) {
1894
- paths.push(arrayPath[1]);
1895
- }
1896
- else {
1897
- paths.push(...path.split('.').filter((p) => p));
1898
- }
1899
- });
1900
- }
1901
- if (field._expressions[prop]) {
1902
- field._expressions[prop].paths = paths;
1903
- }
1904
- return paths;
1905
- }
1906
- }
1907
-
1908
- class FieldValidationExtension {
1909
- constructor(config) {
1910
- this.config = config;
1911
- }
1912
- onPopulate(field) {
1913
- this.initFieldValidation(field, 'validators');
1914
- this.initFieldValidation(field, 'asyncValidators');
1915
- }
1916
- initFieldValidation(field, type) {
1917
- const validators = [];
1918
- if (type === 'validators' && !(field.hasOwnProperty('fieldGroup') && !hasKey(field))) {
1919
- validators.push(this.getPredefinedFieldValidation(field));
1920
- }
1921
- if (field[type]) {
1922
- for (const validatorName of Object.keys(field[type])) {
1923
- validatorName === 'validation'
1924
- ? validators.push(...field[type].validation.map((v) => this.wrapNgValidatorFn(field, v)))
1925
- : validators.push(this.wrapNgValidatorFn(field, field[type][validatorName], validatorName));
1926
- }
1927
- }
1928
- defineHiddenProp(field, '_' + type, validators);
1929
- }
1930
- getPredefinedFieldValidation(field) {
1931
- let VALIDATORS = [];
1932
- FORMLY_VALIDATORS.forEach((opt) => observe(field, ['props', opt], ({ currentValue, firstChange }) => {
1933
- VALIDATORS = VALIDATORS.filter((o) => o !== opt);
1934
- if (opt === 'required' && currentValue != null && typeof currentValue !== 'boolean') {
1935
- console.warn(`Formly: Invalid prop 'required' of type '${typeof currentValue}', expected 'boolean' (Field:${field.key}).`);
1936
- }
1937
- if (currentValue != null && currentValue !== false) {
1938
- VALIDATORS.push(opt);
1939
- }
1940
- if (!firstChange && field.formControl) {
1941
- updateValidity(field.formControl);
1942
- }
1943
- }));
1944
- return (control) => {
1945
- if (VALIDATORS.length === 0) {
1946
- return null;
1947
- }
1948
- return Validators.compose(VALIDATORS.map((opt) => () => {
1949
- var _a, _b, _c, _d;
1950
- const value = field.props[opt];
1951
- switch (opt) {
1952
- case 'required':
1953
- return Validators.required(control);
1954
- case 'pattern':
1955
- return Validators.pattern(value)(control);
1956
- case 'minLength':
1957
- const minLengthResult = Validators.minLength(value)(control);
1958
- const minLengthKey = this.config.getValidatorMessage('minlength') || ((_b = (_a = field.validation) === null || _a === void 0 ? void 0 : _a.messages) === null || _b === void 0 ? void 0 : _b.minlength)
1959
- ? 'minlength'
1960
- : 'minLength';
1961
- return minLengthResult ? { [minLengthKey]: minLengthResult.minlength } : null;
1962
- case 'maxLength':
1963
- const maxLengthResult = Validators.maxLength(value)(control);
1964
- const maxLengthKey = this.config.getValidatorMessage('maxlength') || ((_d = (_c = field.validation) === null || _c === void 0 ? void 0 : _c.messages) === null || _d === void 0 ? void 0 : _d.maxlength)
1965
- ? 'maxlength'
1966
- : 'maxLength';
1967
- return maxLengthResult ? { [maxLengthKey]: maxLengthResult.maxlength } : null;
1968
- case 'min':
1969
- return Validators.min(value)(control);
1970
- case 'max':
1971
- return Validators.max(value)(control);
1972
- default:
1973
- return null;
1974
- }
1975
- }))(control);
1976
- };
1977
- }
1978
- wrapNgValidatorFn(field, validator, validatorName) {
1979
- let validatorOption;
1980
- if (typeof validator === 'string') {
1981
- validatorOption = clone(this.config.getValidator(validator));
1982
- }
1983
- if (typeof validator === 'object' && validator.name) {
1984
- validatorOption = clone(this.config.getValidator(validator.name));
1985
- if (validator.options) {
1986
- validatorOption.options = validator.options;
1987
- }
1988
- }
1989
- if (typeof validator === 'object' && validator.expression) {
1990
- const { expression } = validator, options = __rest(validator, ["expression"]);
1991
- validatorOption = {
1992
- name: validatorName,
1993
- validation: expression,
1994
- options: Object.keys(options).length > 0 ? options : null,
1995
- };
1996
- }
1997
- if (typeof validator === 'function') {
1998
- validatorOption = {
1999
- name: validatorName,
2000
- validation: validator,
2001
- };
2002
- }
2003
- return (control) => {
2004
- const errors = validatorOption.validation(control, field, validatorOption.options);
2005
- if (isPromise(errors)) {
2006
- return errors.then((v) => this.handleResult(field, validatorName ? !!v : v, validatorOption));
2007
- }
2008
- if (isObservable(errors)) {
2009
- return errors.pipe(map((v) => this.handleResult(field, validatorName ? !!v : v, validatorOption)));
2010
- }
2011
- return this.handleResult(field, validatorName ? !!errors : errors, validatorOption);
2012
- };
2013
- }
2014
- handleResult(field, errors, { name, options }) {
2015
- var _a, _b;
2016
- if (typeof errors === 'boolean') {
2017
- errors = errors ? null : { [name]: options ? options : true };
2018
- }
2019
- const ctrl = field.formControl;
2020
- (_b = (_a = ctrl === null || ctrl === void 0 ? void 0 : ctrl._childrenErrors) === null || _a === void 0 ? void 0 : _a[name]) === null || _b === void 0 ? void 0 : _b.call(_a);
2021
- if (isObject(errors)) {
2022
- Object.keys(errors).forEach((name) => {
2023
- const errorPath = errors[name].errorPath ? errors[name].errorPath : options === null || options === void 0 ? void 0 : options.errorPath;
2024
- const childCtrl = errorPath ? field.formControl.get(errorPath) : null;
2025
- if (childCtrl) {
2026
- const _a = errors[name], { errorPath: _errorPath } = _a, opts = __rest(_a, ["errorPath"]);
2027
- childCtrl.setErrors(Object.assign(Object.assign({}, (childCtrl.errors || {})), { [name]: opts }));
2028
- !ctrl._childrenErrors && defineHiddenProp(ctrl, '_childrenErrors', {});
2029
- ctrl._childrenErrors[name] = () => {
2030
- const _a = childCtrl.errors || {}, _b = name, _toDelete = _a[_b], childErrors = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
2031
- childCtrl.setErrors(Object.keys(childErrors).length === 0 ? null : childErrors);
2032
- };
2033
- }
2034
- });
2035
- }
2036
- return errors;
2037
- }
2038
- }
2039
-
2040
- class FieldFormExtension {
2041
- prePopulate(field) {
2042
- if (!this.root) {
2043
- this.root = field;
2044
- }
2045
- if (field.parent) {
2046
- Object.defineProperty(field, 'form', {
2047
- get: () => field.parent.formControl,
2048
- configurable: true,
2049
- });
2050
- }
2051
- }
2052
- onPopulate(field) {
2053
- if (field.hasOwnProperty('fieldGroup') && !hasKey(field)) {
2054
- defineHiddenProp(field, 'formControl', field.form);
2055
- }
2056
- else {
2057
- this.addFormControl(field);
2058
- }
2059
- }
2060
- postPopulate(field) {
2061
- if (this.root !== field) {
2062
- return;
2063
- }
2064
- this.root = null;
2065
- const markForCheck = this.setValidators(field);
2066
- if (markForCheck && field.parent) {
2067
- let parent = field.parent;
2068
- while (parent) {
2069
- if (hasKey(parent) || !parent.parent) {
2070
- updateValidity(parent.formControl, true);
2071
- }
2072
- parent = parent.parent;
2073
- }
2074
- }
2075
- }
2076
- addFormControl(field) {
2077
- let control = findControl(field);
2078
- if (field.fieldArray) {
2079
- return;
2080
- }
2081
- if (!control) {
2082
- const controlOptions = { updateOn: field.modelOptions.updateOn };
2083
- if (field.fieldGroup) {
2084
- control = new FormGroup({}, controlOptions);
2085
- }
2086
- else {
2087
- const value = hasKey(field) ? getFieldValue(field) : field.defaultValue;
2088
- control = new FormControl({ value, disabled: !!field.props.disabled }, Object.assign(Object.assign({}, controlOptions), { initialValueIsDefault: true }));
2089
- }
2090
- }
2091
- else {
2092
- if (control instanceof FormControl) {
2093
- const value = hasKey(field) ? getFieldValue(field) : field.defaultValue;
2094
- control.defaultValue = value;
2095
- }
2096
- }
2097
- registerControl(field, control);
2098
- }
2099
- setValidators(field, disabled = false) {
2100
- var _a, _b;
2101
- if (disabled === false && hasKey(field) && ((_a = field.props) === null || _a === void 0 ? void 0 : _a.disabled)) {
2102
- disabled = true;
2103
- }
2104
- let markForCheck = false;
2105
- (_b = field.fieldGroup) === null || _b === void 0 ? void 0 : _b.forEach((f) => f && this.setValidators(f, disabled) && (markForCheck = true));
2106
- if (hasKey(field) || !field.parent || (!hasKey(field) && !field.fieldGroup)) {
2107
- const { formControl: c } = field;
2108
- if (c) {
2109
- if (hasKey(field) && c instanceof FormControl) {
2110
- if (disabled && c.enabled) {
2111
- c.disable({ emitEvent: false, onlySelf: true });
2112
- markForCheck = true;
2113
- }
2114
- if (!disabled && c.disabled) {
2115
- c.enable({ emitEvent: false, onlySelf: true });
2116
- markForCheck = true;
2117
- }
2118
- }
2119
- if (null === c.validator && this.hasValidators(field, '_validators')) {
2120
- c.setValidators(() => {
2121
- const v = Validators.compose(this.mergeValidators(field, '_validators'));
2122
- return v ? v(c) : null;
2123
- });
2124
- markForCheck = true;
2125
- }
2126
- if (null === c.asyncValidator && this.hasValidators(field, '_asyncValidators')) {
2127
- c.setAsyncValidators(() => {
2128
- const v = Validators.composeAsync(this.mergeValidators(field, '_asyncValidators'));
2129
- return v ? v(c) : of(null);
2130
- });
2131
- markForCheck = true;
2132
- }
2133
- if (markForCheck) {
2134
- updateValidity(c, true);
2135
- // update validity of `FormGroup` instance created by field with nested key.
2136
- let parent = c.parent;
2137
- for (let i = 1; i < getKeyPath(field).length; i++) {
2138
- if (parent) {
2139
- updateValidity(parent, true);
2140
- parent = parent.parent;
2141
- }
2142
- }
2143
- }
2144
- }
2145
- }
2146
- return markForCheck;
2147
- }
2148
- hasValidators(field, type) {
2149
- var _a, _b;
2150
- const c = field.formControl;
2151
- if (((_a = c === null || c === void 0 ? void 0 : c._fields) === null || _a === void 0 ? void 0 : _a.length) > 1 && c._fields.some((f) => f[type].length > 0)) {
2152
- return true;
2153
- }
2154
- else if (field[type].length > 0) {
2155
- return true;
2156
- }
2157
- return (_b = field.fieldGroup) === null || _b === void 0 ? void 0 : _b.some((f) => (f === null || f === void 0 ? void 0 : f.fieldGroup) && !hasKey(f) && this.hasValidators(f, type));
2158
- }
2159
- mergeValidators(field, type) {
2160
- var _a;
2161
- const validators = [];
2162
- const c = field.formControl;
2163
- if (((_a = c === null || c === void 0 ? void 0 : c._fields) === null || _a === void 0 ? void 0 : _a.length) > 1) {
2164
- c._fields
2165
- .filter((f) => !f._hide)
2166
- .forEach((f) => validators.push(...f[type]));
2167
- }
2168
- else if (field[type]) {
2169
- validators.push(...field[type]);
2170
- }
2171
- if (field.fieldGroup) {
2172
- field.fieldGroup
2173
- .filter((f) => (f === null || f === void 0 ? void 0 : f.fieldGroup) && !hasKey(f))
2174
- .forEach((f) => validators.push(...this.mergeValidators(f, type)));
2175
- }
2176
- return validators;
2177
- }
2178
- }
2179
-
2180
- class CoreExtension {
2181
- constructor(config) {
2182
- this.config = config;
2183
- this.formId = 0;
2184
- }
2185
- prePopulate(field) {
2186
- var _a, _b;
2187
- const root = field.parent;
2188
- this.initRootOptions(field);
2189
- this.initFieldProps(field);
2190
- if (root) {
2191
- Object.defineProperty(field, 'options', { get: () => root.options, configurable: true });
2192
- Object.defineProperty(field, 'model', {
2193
- get: () => (hasKey(field) && field.fieldGroup ? getFieldValue(field) : root.model),
2194
- configurable: true,
2195
- });
2196
- }
2197
- Object.defineProperty(field, 'get', {
2198
- value: (key) => getField(field, key),
2199
- configurable: true,
2200
- });
2201
- (_b = (_a = this.getFieldComponentInstance(field)).prePopulate) === null || _b === void 0 ? void 0 : _b.call(_a, field);
2202
- }
2203
- onPopulate(field) {
2204
- var _a, _b;
2205
- this.initFieldOptions(field);
2206
- (_b = (_a = this.getFieldComponentInstance(field)).onPopulate) === null || _b === void 0 ? void 0 : _b.call(_a, field);
2207
- if (field.fieldGroup) {
2208
- field.fieldGroup.forEach((f, index) => {
2209
- if (f) {
2210
- Object.defineProperty(f, 'parent', { get: () => field, configurable: true });
2211
- Object.defineProperty(f, 'index', { get: () => index, configurable: true });
2212
- }
2213
- this.formId++;
2214
- });
2215
- }
2216
- }
2217
- postPopulate(field) {
2218
- var _a, _b;
2219
- (_b = (_a = this.getFieldComponentInstance(field)).postPopulate) === null || _b === void 0 ? void 0 : _b.call(_a, field);
2220
- }
2221
- initFieldProps(field) {
2222
- var _a;
2223
- (_a = field.props) !== null && _a !== void 0 ? _a : (field.props = field.templateOptions);
2224
- Object.defineProperty(field, 'templateOptions', {
2225
- get: () => field.props,
2226
- set: (props) => (field.props = props),
2227
- configurable: true,
2228
- });
2229
- }
2230
- initRootOptions(field) {
2231
- if (field.parent) {
2232
- return;
2233
- }
2234
- const options = field.options;
2235
- field.options.formState = field.options.formState || {};
2236
- if (!options.showError) {
2237
- options.showError = this.config.extras.showError;
2238
- }
2239
- if (!options.fieldChanges) {
2240
- defineHiddenProp(options, 'fieldChanges', new Subject());
2241
- }
2242
- if (!options._hiddenFieldsForCheck) {
2243
- options._hiddenFieldsForCheck = [];
2244
- }
2245
- options._markForCheck = (f) => {
2246
- console.warn(`Formly: 'options._markForCheck' is deprecated since v6.0, use 'options.detectChanges' instead.`);
2247
- options.detectChanges(f);
2248
- };
2249
- options._detectChanges = (f) => {
2250
- var _a;
2251
- if (f._componentRefs) {
2252
- markFieldForCheck(f);
2253
- }
2254
- (_a = f.fieldGroup) === null || _a === void 0 ? void 0 : _a.forEach((f) => f && options._detectChanges(f));
2255
- };
2256
- options.detectChanges = (f) => {
2257
- var _a, _b;
2258
- (_b = (_a = f.options).checkExpressions) === null || _b === void 0 ? void 0 : _b.call(_a, f);
2259
- options._detectChanges(f);
2260
- };
2261
- options.resetModel = (model) => {
2262
- model = clone(model !== null && model !== void 0 ? model : options._initialModel);
2263
- if (field.model) {
2264
- Object.keys(field.model).forEach((k) => delete field.model[k]);
2265
- Object.assign(field.model, model || {});
2266
- }
2267
- if (!isSignalRequired()) {
2268
- observe(options, ['parentForm', 'submitted']).setValue(false, false);
2269
- }
2270
- options.build(field);
2271
- field.form.reset(field.model);
2272
- };
2273
- options.updateInitialValue = (model) => (options._initialModel = clone(model !== null && model !== void 0 ? model : field.model));
2274
- field.options.updateInitialValue();
2275
- }
2276
- initFieldOptions(field) {
2277
- var _a, _b;
2278
- reverseDeepMerge(field, {
2279
- id: getFieldId(`formly_${this.formId}`, field, field.index),
2280
- hooks: {},
2281
- modelOptions: {},
2282
- validation: { messages: {} },
2283
- props: !field.type || !hasKey(field)
2284
- ? {}
2285
- : {
2286
- label: '',
2287
- placeholder: '',
2288
- disabled: false,
2289
- },
2290
- });
2291
- if (this.config.extras.resetFieldOnHide && field.resetOnHide !== false) {
2292
- field.resetOnHide = true;
2293
- }
2294
- if (field.type !== 'formly-template' &&
2295
- (field.template || ((_a = field.expressions) === null || _a === void 0 ? void 0 : _a.template) || ((_b = field.expressionProperties) === null || _b === void 0 ? void 0 : _b.template))) {
2296
- field.type = 'formly-template';
2297
- }
2298
- if (!field.type && field.fieldGroup) {
2299
- field.type = 'formly-group';
2300
- }
2301
- if (field.type) {
2302
- this.config.getMergedField(field);
2303
- }
2304
- if (hasKey(field) &&
2305
- !isUndefined(field.defaultValue) &&
2306
- isUndefined(getFieldValue(field)) &&
2307
- !isHiddenField(field)) {
2308
- assignFieldValue(field, field.defaultValue);
2309
- }
2310
- field.wrappers = field.wrappers || [];
2311
- }
2312
- getFieldComponentInstance(field) {
2313
- const componentRefInstance = () => {
2314
- var _a;
2315
- let componentRef = this.config.resolveFieldTypeRef(field);
2316
- const fieldComponentRef = (_a = field._componentRefs) === null || _a === void 0 ? void 0 : _a.slice(-1)[0];
2317
- if (fieldComponentRef instanceof ComponentRef &&
2318
- (fieldComponentRef === null || fieldComponentRef === void 0 ? void 0 : fieldComponentRef.componentType) === (componentRef === null || componentRef === void 0 ? void 0 : componentRef.componentType)) {
2319
- componentRef = fieldComponentRef;
2320
- }
2321
- return componentRef === null || componentRef === void 0 ? void 0 : componentRef.instance;
2322
- };
2323
- if (!field._proxyInstance) {
2324
- defineHiddenProp(field, '_proxyInstance', new Proxy({}, {
2325
- get: (_, prop) => { var _a; return (_a = componentRefInstance()) === null || _a === void 0 ? void 0 : _a[prop]; },
2326
- set: (_, prop, value) => (componentRefInstance()[prop] = value),
2327
- }));
2328
- }
2329
- return field._proxyInstance;
2330
- }
2331
- }
2332
-
2333
- function defaultFormlyConfig(config) {
2334
- return {
2335
- types: [
2336
- { name: 'formly-group', component: FormlyGroup },
2337
- { name: 'formly-template', component: FormlyTemplateType },
2338
- ],
2339
- extensions: [
2340
- { name: 'core', extension: new CoreExtension(config), priority: -250 },
2341
- { name: 'field-validation', extension: new FieldValidationExtension(config), priority: -200 },
2342
- { name: 'field-form', extension: new FieldFormExtension(), priority: -150 },
2343
- { name: 'field-expression', extension: new FieldExpressionExtension(), priority: -100 },
2344
- ],
2345
- };
2346
- }
2347
- class FormlyModule {
2348
- constructor(configService, configs = []) {
2349
- if (!configs) {
2350
- return;
2351
- }
2352
- configs.forEach((config) => configService.addConfig(config));
2353
- }
2354
- static forRoot(config = {}) {
2355
- return {
2356
- ngModule: FormlyModule,
2357
- providers: [
2358
- { provide: FORMLY_CONFIG, multi: true, useFactory: defaultFormlyConfig, deps: [FormlyConfig] },
2359
- { provide: FORMLY_CONFIG, useValue: config, multi: true },
2360
- FormlyConfig,
2361
- FormlyFormBuilder,
2362
- ],
2363
- };
2364
- }
2365
- static forChild(config = {}) {
2366
- return {
2367
- ngModule: FormlyModule,
2368
- providers: [
2369
- { provide: FORMLY_CONFIG, multi: true, useFactory: defaultFormlyConfig, deps: [FormlyConfig] },
2370
- { provide: FORMLY_CONFIG, useValue: config, multi: true },
2371
- FormlyFormBuilder,
2372
- ],
2373
- };
2374
- }
2375
- }
2376
- FormlyModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyModule, deps: [{ token: FormlyConfig }, { token: FORMLY_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
2377
- FormlyModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyModule, declarations: [FormlyTemplate,
2378
- FormlyForm,
2379
- FormlyField,
2380
- FormlyAttributes,
2381
- FormlyGroup,
2382
- FormlyValidationMessage,
2383
- FormlyTemplateType], imports: [CommonModule], exports: [FormlyTemplate, FormlyForm, FormlyField, FormlyAttributes, FormlyGroup, FormlyValidationMessage] });
2384
- FormlyModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyModule, imports: [[CommonModule]] });
2385
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FormlyModule, decorators: [{
2386
- type: NgModule,
2387
- args: [{
2388
- declarations: [
2389
- FormlyTemplate,
2390
- FormlyForm,
2391
- FormlyField,
2392
- FormlyAttributes,
2393
- FormlyGroup,
2394
- FormlyValidationMessage,
2395
- FormlyTemplateType,
2396
- ],
2397
- exports: [FormlyTemplate, FormlyForm, FormlyField, FormlyAttributes, FormlyGroup, FormlyValidationMessage],
2398
- imports: [CommonModule],
2399
- }]
2400
- }], ctorParameters: function () {
2401
- return [{ type: FormlyConfig }, { type: undefined, decorators: [{
2402
- type: Optional
2403
- }, {
2404
- type: Inject,
2405
- args: [FORMLY_CONFIG]
2406
- }] }];
2407
- } });
2408
-
2409
- /*
2410
- * Public API Surface of core
2411
- */
2412
-
2413
- /**
2414
- * Generated bundle index. Do not edit.
2415
- */
2416
-
2417
- export { FORMLY_CONFIG, FieldArrayType, FieldType, FieldWrapper, FormlyConfig, FormlyField, FormlyForm, FormlyFormBuilder, FormlyModule, FormlyAttributes as ɵFormlyAttributes, FormlyGroup as ɵFormlyGroup, FormlyTemplate as ɵFormlyTemplate, FormlyValidationMessage as ɵFormlyValidationMessage, clone as ɵclone, defineHiddenProp as ɵdefineHiddenProp, getFieldValue as ɵgetFieldValue, hasKey as ɵhasKey, observe as ɵobserve, reverseDeepMerge as ɵreverseDeepMerge };
2418
- //# sourceMappingURL=ngx-formly-core.mjs.map