@ngx-formly/core 5.10.29 → 5.10.33

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.
@@ -1,5 +1,5 @@
1
1
  import { DOCUMENT, CommonModule } from '@angular/common';
2
- import { TemplateRef, Injectable, InjectionToken, NgModule, ANALYZE_FOR_ENTRY_COMPONENTS, Inject, Optional, Component, Input, ChangeDetectionStrategy, EventEmitter, Output, Attribute, ViewChild, ElementRef, NgZone, Directive, Renderer2, ViewContainerRef, ComponentFactoryResolver, Injector, ChangeDetectorRef, defineInjectable, inject, INJECTOR } from '@angular/core';
2
+ import { TemplateRef, Injectable, InjectionToken, NgModule, ANALYZE_FOR_ENTRY_COMPONENTS, Inject, Optional, Component, Input, ChangeDetectionStrategy, EventEmitter, Output, ViewContainerRef, ViewChild, Attribute, ComponentFactoryResolver, Renderer2, ElementRef, Directive, NgZone, Injector, ChangeDetectorRef, defineInjectable, inject, INJECTOR } from '@angular/core';
3
3
  import { DomSanitizer } from '@angular/platform-browser';
4
4
  import { __rest } from 'tslib';
5
5
  import { debounceTime, switchMap, distinctUntilChanged, take, startWith, filter, map } from 'rxjs/operators';
@@ -10,6 +10,21 @@ import { isObservable, Subject, of, merge, Observable } from 'rxjs';
10
10
  * @fileoverview added by tsickle
11
11
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
12
12
  */
13
+ /**
14
+ * @param {?} form
15
+ * @param {?} callback
16
+ * @return {?}
17
+ */
18
+ function disableTreeValidityCall(form, callback) {
19
+ /** @type {?} */
20
+ const _updateTreeValidity = form._updateTreeValidity.bind(form);
21
+ form._updateTreeValidity = (/**
22
+ * @return {?}
23
+ */
24
+ () => { });
25
+ callback();
26
+ form._updateTreeValidity = _updateTreeValidity;
27
+ }
13
28
  /**
14
29
  * @param {?} formId
15
30
  * @param {?} field
@@ -21,8 +36,12 @@ function getFieldId(formId, field, index) {
21
36
  return field.id;
22
37
  /** @type {?} */
23
38
  let type = field.type;
24
- if (!type && field.template)
39
+ if (!type && field.template) {
25
40
  type = 'template';
41
+ }
42
+ if (isFunction(type)) {
43
+ type = ((/** @type {?} */ (type))).prototype.constructor.name;
44
+ }
26
45
  return [formId, type, field.key, index].join('_');
27
46
  }
28
47
  /**
@@ -316,25 +335,6 @@ function wrapProperty(o, prop, setFn) {
316
335
  */
317
336
  () => fns.splice(fns.indexOf(setFn), 1));
318
337
  }
319
- /**
320
- * @param {?} form
321
- * @param {?} action
322
- * @return {?}
323
- */
324
- function reduceFormUpdateValidityCalls(form, action) {
325
- /** @type {?} */
326
- const updateValidity = form._updateTreeValidity.bind(form);
327
- /** @type {?} */
328
- let updateValidityArgs = { called: false, emitEvent: false };
329
- form._updateTreeValidity = (/**
330
- * @param {?=} __0
331
- * @return {?}
332
- */
333
- ({ emitEvent } = { emitEvent: true }) => updateValidityArgs = { called: true, emitEvent: emitEvent || updateValidityArgs.emitEvent });
334
- action();
335
- updateValidityArgs.called && updateValidity({ emitEvent: updateValidityArgs.emitEvent });
336
- form._updateTreeValidity = updateValidity;
337
- }
338
338
 
339
339
  /**
340
340
  * @fileoverview added by tsickle
@@ -651,7 +651,7 @@ class FormlyFormBuilder {
651
651
  }
652
652
  /** @type {?} */
653
653
  const field = { fieldGroup, model, formControl, options: this._setOptions(options) };
654
- reduceFormUpdateValidityCalls(formControl, (/**
654
+ disableTreeValidityCall(formControl, (/**
655
655
  * @return {?}
656
656
  */
657
657
  () => this._buildForm(field)));
@@ -914,15 +914,21 @@ function registerControl(field, control, emitEvent = false) {
914
914
  }
915
915
  /**
916
916
  * @param {?} c
917
+ * @param {?=} onlySelf
917
918
  * @return {?}
918
919
  */
919
- function updateValidity(c) {
920
+ function updateValidity(c, onlySelf = false) {
920
921
  /** @type {?} */
921
922
  const status = c.status;
922
- c.updateValueAndValidity({ emitEvent: false });
923
+ /** @type {?} */
924
+ const value = c.value;
925
+ c.updateValueAndValidity({ emitEvent: false, onlySelf });
923
926
  if (status !== c.status) {
924
927
  ((/** @type {?} */ (c.statusChanges))).emit(c.status);
925
928
  }
929
+ if (value !== c.value) {
930
+ ((/** @type {?} */ (c.valueChanges))).emit(c.value);
931
+ }
926
932
  }
927
933
  /**
928
934
  * @param {?} form
@@ -1646,14 +1652,7 @@ class FormlyAttributes {
1646
1652
  this.renderer = renderer;
1647
1653
  this.elementRef = elementRef;
1648
1654
  this.uiAttributesCache = {};
1649
- this.uiAttributes = [
1650
- ...FORMLY_VALIDATORS,
1651
- 'tabindex',
1652
- 'placeholder',
1653
- 'readonly',
1654
- 'disabled',
1655
- 'step',
1656
- ];
1655
+ this.uiAttributes = null;
1657
1656
  /**
1658
1657
  * HostBinding doesn't register listeners conditionally which may produce some perf issues.
1659
1658
  *
@@ -1661,12 +1660,24 @@ class FormlyAttributes {
1661
1660
  */
1662
1661
  this.uiEvents = {
1663
1662
  listeners: [],
1664
- events: [
1665
- 'click',
1666
- 'keyup',
1667
- 'keydown',
1668
- 'keypress',
1669
- ],
1663
+ events: ['click', 'keyup', 'keydown', 'keypress', 'focus', 'blur', 'change'],
1664
+ callback: (/**
1665
+ * @param {?} eventName
1666
+ * @param {?} $event
1667
+ * @return {?}
1668
+ */
1669
+ (eventName, $event) => {
1670
+ switch (eventName) {
1671
+ case 'focus':
1672
+ return this.onFocus($event);
1673
+ case 'blur':
1674
+ return this.onBlur($event);
1675
+ case 'change':
1676
+ return this.onChange($event);
1677
+ default:
1678
+ return this.to[eventName](this.field, $event);
1679
+ }
1680
+ }),
1670
1681
  };
1671
1682
  this.document = _document;
1672
1683
  }
@@ -1690,18 +1701,18 @@ class FormlyAttributes {
1690
1701
  * @param {?} listener
1691
1702
  * @return {?}
1692
1703
  */
1693
- listener => listener()));
1704
+ (listener) => listener()));
1694
1705
  this.uiEvents.events.forEach((/**
1695
1706
  * @param {?} eventName
1696
1707
  * @return {?}
1697
1708
  */
1698
- eventName => {
1699
- if (this.to && this.to[eventName]) {
1709
+ (eventName) => {
1710
+ if ((this.to && this.to[eventName]) || ['focus', 'blur', 'change'].indexOf(eventName) !== -1) {
1700
1711
  this.uiEvents.listeners.push(this.renderer.listen(this.elementRef.nativeElement, eventName, (/**
1701
1712
  * @param {?} e
1702
1713
  * @return {?}
1703
1714
  */
1704
- (e) => this.to[eventName](this.field, e))));
1715
+ (e) => this.uiEvents.callback(eventName, e))));
1705
1716
  }
1706
1717
  }));
1707
1718
  if (this.to && this.to.attributes) {
@@ -1757,6 +1768,15 @@ class FormlyAttributes {
1757
1768
  * @return {?}
1758
1769
  */
1759
1770
  ngDoCheck() {
1771
+ if (!this.uiAttributes) {
1772
+ /** @type {?} */
1773
+ const element = (/** @type {?} */ (this.elementRef.nativeElement));
1774
+ this.uiAttributes = [...FORMLY_VALIDATORS, 'tabindex', 'placeholder', 'readonly', 'disabled', 'step'].filter((/**
1775
+ * @param {?} attr
1776
+ * @return {?}
1777
+ */
1778
+ (attr) => !element.hasAttribute || !element.hasAttribute(attr)));
1779
+ }
1760
1780
  this.uiAttributes.forEach((/**
1761
1781
  * @param {?} attr
1762
1782
  * @return {?}
@@ -1832,6 +1852,17 @@ class FormlyAttributes {
1832
1852
  this.to.blur(this.field, $event);
1833
1853
  }
1834
1854
  }
1855
+ // handle custom `change` event, for regular ones rely on DOM listener
1856
+ /**
1857
+ * @param {?} $event
1858
+ * @return {?}
1859
+ */
1860
+ onHostChange($event) {
1861
+ if ($event instanceof Event) {
1862
+ return;
1863
+ }
1864
+ this.onChange($event);
1865
+ }
1835
1866
  /**
1836
1867
  * @param {?} $event
1837
1868
  * @return {?}
@@ -1894,9 +1925,7 @@ FormlyAttributes.decorators = [
1894
1925
  { type: Directive, args: [{
1895
1926
  selector: '[formlyAttributes]',
1896
1927
  host: {
1897
- '(focus)': 'onFocus($event)',
1898
- '(blur)': 'onBlur($event)',
1899
- '(change)': 'onChange($event)',
1928
+ '(change)': 'onHostChange($event)',
1900
1929
  },
1901
1930
  },] }
1902
1931
  ];
@@ -2306,10 +2335,7 @@ class FieldExpressionExtension {
2306
2335
  (f, ignoreCache) => {
2307
2336
  if (!checkLocked) {
2308
2337
  checkLocked = true;
2309
- reduceFormUpdateValidityCalls(f.formControl, (/**
2310
- * @return {?}
2311
- */
2312
- () => this.checkField(f, ignoreCache)));
2338
+ this.checkField(f, ignoreCache);
2313
2339
  checkLocked = false;
2314
2340
  }
2315
2341
  });
@@ -2982,22 +3008,7 @@ class FieldFormExtension {
2982
3008
  if (field.parent) {
2983
3009
  return;
2984
3010
  }
2985
- /** @type {?} */
2986
- const fieldsToUpdate = this.setValidators(field);
2987
- if (fieldsToUpdate.length === 0) {
2988
- return;
2989
- }
2990
- if (fieldsToUpdate.length === 1) {
2991
- /** @type {?} */
2992
- let control = fieldsToUpdate[0].formControl;
2993
- while (control) {
2994
- ((/** @type {?} */ (control)))._updateTreeValidity({ onlySelf: true });
2995
- control = control.parent;
2996
- }
2997
- }
2998
- else {
2999
- ((/** @type {?} */ (field.formControl)))._updateTreeValidity();
3000
- }
3011
+ this.setValidators(field);
3001
3012
  }
3002
3013
  /**
3003
3014
  * @private
@@ -3033,33 +3044,31 @@ class FieldFormExtension {
3033
3044
  /**
3034
3045
  * @private
3035
3046
  * @param {?} field
3047
+ * @param {?=} disabled
3036
3048
  * @return {?}
3037
3049
  */
3038
- setValidators(field) {
3050
+ setValidators(field, disabled = false) {
3039
3051
  /** @type {?} */
3040
- let updateValidity$$1 = false;
3052
+ let markForCheck = false;
3053
+ if (disabled === false && field.key && field.templateOptions && field.templateOptions.disabled) {
3054
+ disabled = true;
3055
+ }
3056
+ (field.fieldGroup || []).forEach((/**
3057
+ * @param {?} f
3058
+ * @return {?}
3059
+ */
3060
+ f => this.setValidators(f, disabled) && (markForCheck = true)));
3041
3061
  if (field.key || !field.parent || (!field.key && !field.fieldGroup)) {
3042
3062
  const { formControl: c } = field;
3043
- /** @type {?} */
3044
- const disabled = field.templateOptions ? field.templateOptions.disabled : false;
3045
- if (field.key && c) {
3063
+ field.templateOptions = field.templateOptions || {};
3064
+ if (field.key && c && c instanceof FormControl) {
3046
3065
  if (disabled && c.enabled) {
3047
3066
  c.disable({ emitEvent: false, onlySelf: true });
3048
- if (!c.parent) {
3049
- updateValidity(c);
3050
- }
3051
- else {
3052
- updateValidity$$1 = true;
3053
- }
3067
+ markForCheck = true;
3054
3068
  }
3055
3069
  if (!disabled && c.disabled) {
3056
3070
  c.enable({ emitEvent: false, onlySelf: true });
3057
- if (!c.parent) {
3058
- updateValidity(c);
3059
- }
3060
- else {
3061
- updateValidity$$1 = true;
3062
- }
3071
+ markForCheck = true;
3063
3072
  }
3064
3073
  }
3065
3074
  if (c && (null === c.validator || null === c.asyncValidator)) {
@@ -3079,28 +3088,13 @@ class FieldFormExtension {
3079
3088
  const v = Validators.composeAsync(this.mergeValidators(field, '_asyncValidators'));
3080
3089
  return v ? v(c) : of(null);
3081
3090
  }));
3082
- if (!c.parent) {
3083
- updateValidity(c);
3084
- }
3085
- else {
3086
- updateValidity$$1 = true;
3087
- }
3091
+ markForCheck = true;
3088
3092
  }
3089
- }
3090
- /** @type {?} */
3091
- const fieldsToUpdate = updateValidity$$1 ? [field] : [];
3092
- (field.fieldGroup || []).forEach((/**
3093
- * @param {?} f
3094
- * @return {?}
3095
- */
3096
- f => {
3097
- /** @type {?} */
3098
- const childrenToUpdate = this.setValidators(f);
3099
- if (!updateValidity$$1) {
3100
- fieldsToUpdate.push(...childrenToUpdate);
3093
+ if (markForCheck) {
3094
+ updateValidity(c, true);
3101
3095
  }
3102
- }));
3103
- return fieldsToUpdate;
3096
+ }
3097
+ return markForCheck;
3104
3098
  }
3105
3099
  /**
3106
3100
  * @private