| /** |
| * @license Angular v8.1.1 |
| * (c) 2010-2019 Google LLC. https://angular.io/ |
| * License: MIT |
| */ |
| |
| import { InjectionToken, forwardRef, Directive, Renderer2, ElementRef, Optional, Inject, Self, ɵisPromise, ɵisObservable, Injectable, Injector, Input, ɵlooseIdentical, Host, isDevMode, EventEmitter, SkipSelf, Output, NgModule, Version } from '@angular/core'; |
| import { ɵgetDOM } from '@angular/platform-browser'; |
| import { forkJoin, from } from 'rxjs'; |
| import { map } from 'rxjs/operators'; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * Used to provide a `ControlValueAccessor` for form controls. |
| * |
| * See `DefaultValueAccessor` for how to implement one. |
| * |
| * \@publicApi |
| * @type {?} |
| */ |
| const NG_VALUE_ACCESSOR = new InjectionToken('NgValueAccessor'); |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const CHECKBOX_VALUE_ACCESSOR = { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => CheckboxControlValueAccessor)), |
| multi: true, |
| }; |
| /** |
| * \@description |
| * A `ControlValueAccessor` for writing a value and listening to changes on a checkbox input |
| * element. |
| * |
| * \@usageNotes |
| * |
| * ### Using a checkbox with a reactive form. |
| * |
| * The following example shows how to use a checkbox with a reactive form. |
| * |
| * ```ts |
| * const rememberLoginControl = new FormControl(); |
| * ``` |
| * |
| * ``` |
| * <input type="checkbox" [formControl]="rememberLoginControl"> |
| * ``` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class CheckboxControlValueAccessor { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| */ |
| constructor(_renderer, _elementRef) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| /** |
| * \@description |
| * The registered callback function called when a change event occurs on the input element. |
| */ |
| this.onChange = (/** |
| * @param {?} _ |
| * @return {?} |
| */ |
| (_) => { }); |
| /** |
| * \@description |
| * The registered callback function called when a blur event occurs on the input element. |
| */ |
| this.onTouched = (/** |
| * @return {?} |
| */ |
| () => { }); |
| } |
| /** |
| * Sets the "checked" property on the input element. |
| * |
| * @param {?} value The checked value |
| * @return {?} |
| */ |
| writeValue(value) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'checked', value); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control value changes. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnChange(fn) { this.onChange = fn; } |
| /** |
| * \@description |
| * Registers a function called when the control is touched. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnTouched(fn) { this.onTouched = fn; } |
| /** |
| * Sets the "disabled" property on the input element. |
| * |
| * @param {?} isDisabled The disabled value |
| * @return {?} |
| */ |
| setDisabledState(isDisabled) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); |
| } |
| } |
| CheckboxControlValueAccessor.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]', |
| host: { '(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()' }, |
| providers: [CHECKBOX_VALUE_ACCESSOR] |
| },] } |
| ]; |
| /** @nocollapse */ |
| CheckboxControlValueAccessor.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const DEFAULT_VALUE_ACCESSOR = { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => DefaultValueAccessor)), |
| multi: true |
| }; |
| /** |
| * We must check whether the agent is Android because composition events |
| * behave differently between iOS and Android. |
| * @return {?} |
| */ |
| function _isAndroid() { |
| /** @type {?} */ |
| const userAgent = ɵgetDOM() ? ɵgetDOM().getUserAgent() : ''; |
| return /android (\d+)/.test(userAgent.toLowerCase()); |
| } |
| /** |
| * \@description |
| * Provide this token to control if form directives buffer IME input until |
| * the "compositionend" event occurs. |
| * \@publicApi |
| * @type {?} |
| */ |
| const COMPOSITION_BUFFER_MODE = new InjectionToken('CompositionEventMode'); |
| /** |
| * \@description |
| * The default `ControlValueAccessor` for writing a value and listening to changes on input |
| * elements. The accessor is used by the `FormControlDirective`, `FormControlName`, and |
| * `NgModel` directives. |
| * |
| * \@usageNotes |
| * |
| * ### Using the default value accessor |
| * |
| * The following example shows how to use an input element that activates the default value accessor |
| * (in this case, a text field). |
| * |
| * ```ts |
| * const firstNameControl = new FormControl(); |
| * ``` |
| * |
| * ``` |
| * <input type="text" [formControl]="firstNameControl"> |
| * ``` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class DefaultValueAccessor { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| * @param {?} _compositionMode |
| */ |
| constructor(_renderer, _elementRef, _compositionMode) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| this._compositionMode = _compositionMode; |
| /** |
| * \@description |
| * The registered callback function called when an input event occurs on the input element. |
| */ |
| this.onChange = (/** |
| * @param {?} _ |
| * @return {?} |
| */ |
| (_) => { }); |
| /** |
| * \@description |
| * The registered callback function called when a blur event occurs on the input element. |
| */ |
| this.onTouched = (/** |
| * @return {?} |
| */ |
| () => { }); |
| /** |
| * Whether the user is creating a composition string (IME events). |
| */ |
| this._composing = false; |
| if (this._compositionMode == null) { |
| this._compositionMode = !_isAndroid(); |
| } |
| } |
| /** |
| * Sets the "value" property on the input element. |
| * |
| * @param {?} value The checked value |
| * @return {?} |
| */ |
| writeValue(value) { |
| /** @type {?} */ |
| const normalizedValue = value == null ? '' : value; |
| this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control value changes. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnChange(fn) { this.onChange = fn; } |
| /** |
| * \@description |
| * Registers a function called when the control is touched. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnTouched(fn) { this.onTouched = fn; } |
| /** |
| * Sets the "disabled" property on the input element. |
| * |
| * @param {?} isDisabled The disabled value |
| * @return {?} |
| */ |
| setDisabledState(isDisabled) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); |
| } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _handleInput(value) { |
| if (!this._compositionMode || (this._compositionMode && !this._composing)) { |
| this.onChange(value); |
| } |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _compositionStart() { this._composing = true; } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _compositionEnd(value) { |
| this._composing = false; |
| this._compositionMode && this.onChange(value); |
| } |
| } |
| DefaultValueAccessor.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]', |
| // TODO: vsavkin replace the above selector with the one below it once |
| // https://github.com/angular/angular/issues/3011 is implemented |
| // selector: '[ngModel],[formControl],[formControlName]', |
| host: { |
| '(input)': '$any(this)._handleInput($event.target.value)', |
| '(blur)': 'onTouched()', |
| '(compositionstart)': '$any(this)._compositionStart()', |
| '(compositionend)': '$any(this)._compositionEnd($event.target.value)' |
| }, |
| providers: [DEFAULT_VALUE_ACCESSOR] |
| },] } |
| ]; |
| /** @nocollapse */ |
| DefaultValueAccessor.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef }, |
| { type: Boolean, decorators: [{ type: Optional }, { type: Inject, args: [COMPOSITION_BUFFER_MODE,] }] } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * @license |
| * Copyright Google Inc. All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * \@description |
| * Base class for control directives. |
| * |
| * This class is only used internally in the `ReactiveFormsModule` and the `FormsModule`. |
| * |
| * \@publicApi |
| * @abstract |
| */ |
| class AbstractControlDirective { |
| /** |
| * \@description |
| * Reports the value of the control if it is present, otherwise null. |
| * @return {?} |
| */ |
| get value() { return this.control ? this.control.value : null; } |
| /** |
| * \@description |
| * Reports whether the control is valid. A control is considered valid if no |
| * validation errors exist with the current value. |
| * If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get valid() { return this.control ? this.control.valid : null; } |
| /** |
| * \@description |
| * Reports whether the control is invalid, meaning that an error exists in the input value. |
| * If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get invalid() { return this.control ? this.control.invalid : null; } |
| /** |
| * \@description |
| * Reports whether a control is pending, meaning that that async validation is occurring and |
| * errors are not yet available for the input value. If the control is not present, null is |
| * returned. |
| * @return {?} |
| */ |
| get pending() { return this.control ? this.control.pending : null; } |
| /** |
| * \@description |
| * Reports whether the control is disabled, meaning that the control is disabled |
| * in the UI and is exempt from validation checks and excluded from aggregate |
| * values of ancestor controls. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get disabled() { return this.control ? this.control.disabled : null; } |
| /** |
| * \@description |
| * Reports whether the control is enabled, meaning that the control is included in ancestor |
| * calculations of validity or value. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get enabled() { return this.control ? this.control.enabled : null; } |
| /** |
| * \@description |
| * Reports the control's validation errors. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get errors() { return this.control ? this.control.errors : null; } |
| /** |
| * \@description |
| * Reports whether the control is pristine, meaning that the user has not yet changed |
| * the value in the UI. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get pristine() { return this.control ? this.control.pristine : null; } |
| /** |
| * \@description |
| * Reports whether the control is dirty, meaning that the user has changed |
| * the value in the UI. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get dirty() { return this.control ? this.control.dirty : null; } |
| /** |
| * \@description |
| * Reports whether the control is touched, meaning that the user has triggered |
| * a `blur` event on it. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get touched() { return this.control ? this.control.touched : null; } |
| /** |
| * \@description |
| * Reports the validation status of the control. Possible values include: |
| * 'VALID', 'INVALID', 'DISABLED', and 'PENDING'. |
| * If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get status() { return this.control ? this.control.status : null; } |
| /** |
| * \@description |
| * Reports whether the control is untouched, meaning that the user has not yet triggered |
| * a `blur` event on it. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get untouched() { return this.control ? this.control.untouched : null; } |
| /** |
| * \@description |
| * Returns a multicasting observable that emits a validation status whenever it is |
| * calculated for the control. If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get statusChanges() { |
| return this.control ? this.control.statusChanges : null; |
| } |
| /** |
| * \@description |
| * Returns a multicasting observable of value changes for the control that emits every time the |
| * value of the control changes in the UI or programmatically. |
| * If the control is not present, null is returned. |
| * @return {?} |
| */ |
| get valueChanges() { |
| return this.control ? this.control.valueChanges : null; |
| } |
| /** |
| * \@description |
| * Returns an array that represents the path from the top-level form to this control. |
| * Each index is the string name of the control on that level. |
| * @return {?} |
| */ |
| get path() { return null; } |
| /** |
| * \@description |
| * Resets the control with the provided value if the control is present. |
| * @param {?=} value |
| * @return {?} |
| */ |
| reset(value = undefined) { |
| if (this.control) |
| this.control.reset(value); |
| } |
| /** |
| * \@description |
| * Reports whether the control with the given path has the error specified. |
| * |
| * \@usageNotes |
| * For example, for the following `FormGroup`: |
| * |
| * ``` |
| * form = new FormGroup({ |
| * address: new FormGroup({ street: new FormControl() }) |
| * }); |
| * ``` |
| * |
| * The path to the 'street' control from the root form would be 'address' -> 'street'. |
| * |
| * It can be provided to this method in one of two formats: |
| * |
| * 1. An array of string control names, e.g. `['address', 'street']` |
| * 1. A period-delimited list of control names in one string, e.g. `'address.street'` |
| * |
| * If no path is given, this method checks for the error on the current control. |
| * |
| * @param {?} errorCode The code of the error to check |
| * @param {?=} path A list of control names that designates how to move from the current control |
| * to the control that should be queried for errors. |
| * |
| * @return {?} whether the given error is present in the control at the given path. |
| * |
| * If the control is not present, false is returned. |
| */ |
| hasError(errorCode, path) { |
| return this.control ? this.control.hasError(errorCode, path) : false; |
| } |
| /** |
| * \@description |
| * Reports error data for the control with the given path. |
| * |
| * \@usageNotes |
| * For example, for the following `FormGroup`: |
| * |
| * ``` |
| * form = new FormGroup({ |
| * address: new FormGroup({ street: new FormControl() }) |
| * }); |
| * ``` |
| * |
| * The path to the 'street' control from the root form would be 'address' -> 'street'. |
| * |
| * It can be provided to this method in one of two formats: |
| * |
| * 1. An array of string control names, e.g. `['address', 'street']` |
| * 1. A period-delimited list of control names in one string, e.g. `'address.street'` |
| * |
| * @param {?} errorCode The code of the error to check |
| * @param {?=} path A list of control names that designates how to move from the current control |
| * to the control that should be queried for errors. |
| * |
| * @return {?} error data for that particular error. If the control or error is not present, |
| * null is returned. |
| */ |
| getError(errorCode, path) { |
| return this.control ? this.control.getError(errorCode, path) : null; |
| } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * \@description |
| * A base class for directives that contain multiple registered instances of `NgControl`. |
| * Only used by the forms module. |
| * |
| * \@publicApi |
| * @abstract |
| */ |
| class ControlContainer extends AbstractControlDirective { |
| /** |
| * \@description |
| * The top-level form directive for the control. |
| * @return {?} |
| */ |
| get formDirective() { return null; } |
| /** |
| * \@description |
| * The path to this group. |
| * @return {?} |
| */ |
| get path() { return null; } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * @return {?} |
| */ |
| function unimplemented() { |
| throw new Error('unimplemented'); |
| } |
| /** |
| * \@description |
| * A base class that all control `FormControl`-based directives extend. It binds a `FormControl` |
| * object to a DOM element. |
| * |
| * \@publicApi |
| * @abstract |
| */ |
| class NgControl extends AbstractControlDirective { |
| constructor() { |
| super(...arguments); |
| /** |
| * \@description |
| * The parent form for the control. |
| * |
| * \@internal |
| */ |
| this._parent = null; |
| /** |
| * \@description |
| * The name for the control |
| */ |
| this.name = null; |
| /** |
| * \@description |
| * The value accessor for the control |
| */ |
| this.valueAccessor = null; |
| /** |
| * \@description |
| * The uncomposed array of synchronous validators for the control |
| * |
| * \@internal |
| */ |
| this._rawValidators = []; |
| /** |
| * \@description |
| * The uncomposed array of async validators for the control |
| * |
| * \@internal |
| */ |
| this._rawAsyncValidators = []; |
| } |
| /** |
| * \@description |
| * The registered synchronous validator function for the control |
| * |
| * @throws An exception that this method is not implemented |
| * @return {?} |
| */ |
| get validator() { return (/** @type {?} */ (unimplemented())); } |
| /** |
| * \@description |
| * The registered async validator function for the control |
| * |
| * @throws An exception that this method is not implemented |
| * @return {?} |
| */ |
| get asyncValidator() { return (/** @type {?} */ (unimplemented())); } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| class AbstractControlStatus { |
| /** |
| * @param {?} cd |
| */ |
| constructor(cd) { this._cd = cd; } |
| /** |
| * @return {?} |
| */ |
| get ngClassUntouched() { return this._cd.control ? this._cd.control.untouched : false; } |
| /** |
| * @return {?} |
| */ |
| get ngClassTouched() { return this._cd.control ? this._cd.control.touched : false; } |
| /** |
| * @return {?} |
| */ |
| get ngClassPristine() { return this._cd.control ? this._cd.control.pristine : false; } |
| /** |
| * @return {?} |
| */ |
| get ngClassDirty() { return this._cd.control ? this._cd.control.dirty : false; } |
| /** |
| * @return {?} |
| */ |
| get ngClassValid() { return this._cd.control ? this._cd.control.valid : false; } |
| /** |
| * @return {?} |
| */ |
| get ngClassInvalid() { return this._cd.control ? this._cd.control.invalid : false; } |
| /** |
| * @return {?} |
| */ |
| get ngClassPending() { return this._cd.control ? this._cd.control.pending : false; } |
| } |
| /** @type {?} */ |
| const ngControlStatusHost = { |
| '[class.ng-untouched]': 'ngClassUntouched', |
| '[class.ng-touched]': 'ngClassTouched', |
| '[class.ng-pristine]': 'ngClassPristine', |
| '[class.ng-dirty]': 'ngClassDirty', |
| '[class.ng-valid]': 'ngClassValid', |
| '[class.ng-invalid]': 'ngClassInvalid', |
| '[class.ng-pending]': 'ngClassPending', |
| }; |
| /** |
| * \@description |
| * Directive automatically applied to Angular form controls that sets CSS classes |
| * based on control status. |
| * |
| * \@usageNotes |
| * |
| * ### CSS classes applied |
| * |
| * The following classes are applied as the properties become true: |
| * |
| * * ng-valid |
| * * ng-invalid |
| * * ng-pending |
| * * ng-pristine |
| * * ng-dirty |
| * * ng-untouched |
| * * ng-touched |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NgControlStatus extends AbstractControlStatus { |
| /** |
| * @param {?} cd |
| */ |
| constructor(cd) { super(cd); } |
| } |
| NgControlStatus.decorators = [ |
| { type: Directive, args: [{ selector: '[formControlName],[ngModel],[formControl]', host: ngControlStatusHost },] } |
| ]; |
| /** @nocollapse */ |
| NgControlStatus.ctorParameters = () => [ |
| { type: NgControl, decorators: [{ type: Self }] } |
| ]; |
| /** |
| * \@description |
| * Directive automatically applied to Angular form groups that sets CSS classes |
| * based on control status (valid/invalid/dirty/etc). |
| * |
| * @see `NgControlStatus` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NgControlStatusGroup extends AbstractControlStatus { |
| /** |
| * @param {?} cd |
| */ |
| constructor(cd) { super(cd); } |
| } |
| NgControlStatusGroup.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]', |
| host: ngControlStatusHost |
| },] } |
| ]; |
| /** @nocollapse */ |
| NgControlStatusGroup.ctorParameters = () => [ |
| { type: ControlContainer, decorators: [{ type: Self }] } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * @param {?} value |
| * @return {?} |
| */ |
| function isEmptyInputValue(value) { |
| // we don't check for string here so it also works with arrays |
| return value == null || value.length === 0; |
| } |
| /** |
| * \@description |
| * An `InjectionToken` for registering additional synchronous validators used with `AbstractControl`s. |
| * |
| * @see `NG_ASYNC_VALIDATORS` |
| * |
| * \@usageNotes |
| * |
| * ### Providing a custom validator |
| * |
| * The following example registers a custom validator directive. Adding the validator to the |
| * existing collection of validators requires the `multi: true` option. |
| * |
| * ```typescript |
| * \@Directive({ |
| * selector: '[customValidator]', |
| * providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}] |
| * }) |
| * class CustomValidatorDirective implements Validator { |
| * validate(control: AbstractControl): ValidationErrors | null { |
| * return { 'custom': true }; |
| * } |
| * } |
| * ``` |
| * |
| * \@publicApi |
| * @type {?} |
| */ |
| const NG_VALIDATORS = new InjectionToken('NgValidators'); |
| /** |
| * \@description |
| * An `InjectionToken` for registering additional asynchronous validators used with `AbstractControl`s. |
| * |
| * @see `NG_VALIDATORS` |
| * |
| * \@publicApi |
| * @type {?} |
| */ |
| const NG_ASYNC_VALIDATORS = new InjectionToken('NgAsyncValidators'); |
| /** @type {?} */ |
| const EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/; |
| /** |
| * \@description |
| * Provides a set of built-in validators that can be used by form controls. |
| * |
| * A validator is a function that processes a `FormControl` or collection of |
| * controls and returns an error map or null. A null map means that validation has passed. |
| * |
| * @see [Form Validation](/guide/form-validation) |
| * |
| * \@publicApi |
| */ |
| class Validators { |
| /** |
| * \@description |
| * Validator that requires the control's value to be greater than or equal to the provided number. |
| * The validator exists only as a function and not as a directive. |
| * |
| * \@usageNotes |
| * |
| * ### Validate against a minimum of 3 |
| * |
| * ```typescript |
| * const control = new FormControl(2, Validators.min(3)); |
| * |
| * console.log(control.errors); // {min: {min: 3, actual: 2}} |
| * ``` |
| * |
| * @param {?} min |
| * @return {?} A validator function that returns an error map with the |
| * `min` property if the validation check fails, otherwise `null`. |
| * |
| */ |
| static min(min) { |
| return (/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { |
| if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) { |
| return null; // don't validate empty values to allow optional controls |
| } |
| /** @type {?} */ |
| const value = parseFloat(control.value); |
| // Controls with NaN values after parsing should be treated as not having a |
| // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min |
| return !isNaN(value) && value < min ? { 'min': { 'min': min, 'actual': control.value } } : null; |
| }); |
| } |
| /** |
| * \@description |
| * Validator that requires the control's value to be less than or equal to the provided number. |
| * The validator exists only as a function and not as a directive. |
| * |
| * \@usageNotes |
| * |
| * ### Validate against a maximum of 15 |
| * |
| * ```typescript |
| * const control = new FormControl(16, Validators.max(15)); |
| * |
| * console.log(control.errors); // {max: {max: 15, actual: 16}} |
| * ``` |
| * |
| * @param {?} max |
| * @return {?} A validator function that returns an error map with the |
| * `max` property if the validation check fails, otherwise `null`. |
| * |
| */ |
| static max(max) { |
| return (/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { |
| if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) { |
| return null; // don't validate empty values to allow optional controls |
| } |
| /** @type {?} */ |
| const value = parseFloat(control.value); |
| // Controls with NaN values after parsing should be treated as not having a |
| // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max |
| return !isNaN(value) && value > max ? { 'max': { 'max': max, 'actual': control.value } } : null; |
| }); |
| } |
| /** |
| * \@description |
| * Validator that requires the control have a non-empty value. |
| * |
| * \@usageNotes |
| * |
| * ### Validate that the field is non-empty |
| * |
| * ```typescript |
| * const control = new FormControl('', Validators.required); |
| * |
| * console.log(control.errors); // {required: true} |
| * ``` |
| * |
| * @param {?} control |
| * @return {?} An error map with the `required` property |
| * if the validation check fails, otherwise `null`. |
| * |
| */ |
| static required(control) { |
| return isEmptyInputValue(control.value) ? { 'required': true } : null; |
| } |
| /** |
| * \@description |
| * Validator that requires the control's value be true. This validator is commonly |
| * used for required checkboxes. |
| * |
| * \@usageNotes |
| * |
| * ### Validate that the field value is true |
| * |
| * ```typescript |
| * const control = new FormControl('', Validators.requiredTrue); |
| * |
| * console.log(control.errors); // {required: true} |
| * ``` |
| * |
| * @param {?} control |
| * @return {?} An error map that contains the `required` property |
| * set to `true` if the validation check fails, otherwise `null`. |
| */ |
| static requiredTrue(control) { |
| return control.value === true ? null : { 'required': true }; |
| } |
| /** |
| * \@description |
| * Validator that requires the control's value pass an email validation test. |
| * |
| * \@usageNotes |
| * |
| * ### Validate that the field matches a valid email pattern |
| * |
| * ```typescript |
| * const control = new FormControl('bad\@', Validators.email); |
| * |
| * console.log(control.errors); // {email: true} |
| * ``` |
| * |
| * @param {?} control |
| * @return {?} An error map with the `email` property |
| * if the validation check fails, otherwise `null`. |
| * |
| */ |
| static email(control) { |
| if (isEmptyInputValue(control.value)) { |
| return null; // don't validate empty values to allow optional controls |
| } |
| return EMAIL_REGEXP.test(control.value) ? null : { 'email': true }; |
| } |
| /** |
| * \@description |
| * Validator that requires the length of the control's value to be greater than or equal |
| * to the provided minimum length. This validator is also provided by default if you use the |
| * the HTML5 `minlength` attribute. |
| * |
| * \@usageNotes |
| * |
| * ### Validate that the field has a minimum of 3 characters |
| * |
| * ```typescript |
| * const control = new FormControl('ng', Validators.minLength(3)); |
| * |
| * console.log(control.errors); // {minlength: {requiredLength: 3, actualLength: 2}} |
| * ``` |
| * |
| * ```html |
| * <input minlength="5"> |
| * ``` |
| * |
| * @param {?} minLength |
| * @return {?} A validator function that returns an error map with the |
| * `minlength` if the validation check fails, otherwise `null`. |
| */ |
| static minLength(minLength) { |
| return (/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { |
| if (isEmptyInputValue(control.value)) { |
| return null; // don't validate empty values to allow optional controls |
| } |
| /** @type {?} */ |
| const length = control.value ? control.value.length : 0; |
| return length < minLength ? |
| { 'minlength': { 'requiredLength': minLength, 'actualLength': length } } : |
| null; |
| }); |
| } |
| /** |
| * \@description |
| * Validator that requires the length of the control's value to be less than or equal |
| * to the provided maximum length. This validator is also provided by default if you use the |
| * the HTML5 `maxlength` attribute. |
| * |
| * \@usageNotes |
| * |
| * ### Validate that the field has maximum of 5 characters |
| * |
| * ```typescript |
| * const control = new FormControl('Angular', Validators.maxLength(5)); |
| * |
| * console.log(control.errors); // {maxlength: {requiredLength: 5, actualLength: 7}} |
| * ``` |
| * |
| * ```html |
| * <input maxlength="5"> |
| * ``` |
| * |
| * @param {?} maxLength |
| * @return {?} A validator function that returns an error map with the |
| * `maxlength` property if the validation check fails, otherwise `null`. |
| */ |
| static maxLength(maxLength) { |
| return (/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { |
| /** @type {?} */ |
| const length = control.value ? control.value.length : 0; |
| return length > maxLength ? |
| { 'maxlength': { 'requiredLength': maxLength, 'actualLength': length } } : |
| null; |
| }); |
| } |
| /** |
| * \@description |
| * Validator that requires the control's value to match a regex pattern. This validator is also |
| * provided by default if you use the HTML5 `pattern` attribute. |
| * |
| * Note that if a Regexp is provided, the Regexp is used as is to test the values. On the other |
| * hand, if a string is passed, the `^` character is prepended and the `$` character is |
| * appended to the provided string (if not already present), and the resulting regular |
| * expression is used to test the values. |
| * |
| * \@usageNotes |
| * |
| * ### Validate that the field only contains letters or spaces |
| * |
| * ```typescript |
| * const control = new FormControl('1', Validators.pattern('[a-zA-Z ]*')); |
| * |
| * console.log(control.errors); // {pattern: {requiredPattern: '^[a-zA-Z ]*$', actualValue: '1'}} |
| * ``` |
| * |
| * ```html |
| * <input pattern="[a-zA-Z ]*"> |
| * ``` |
| * |
| * @param {?} pattern |
| * @return {?} A validator function that returns an error map with the |
| * `pattern` property if the validation check fails, otherwise `null`. |
| */ |
| static pattern(pattern) { |
| if (!pattern) |
| return Validators.nullValidator; |
| /** @type {?} */ |
| let regex; |
| /** @type {?} */ |
| let regexStr; |
| if (typeof pattern === 'string') { |
| regexStr = ''; |
| if (pattern.charAt(0) !== '^') |
| regexStr += '^'; |
| regexStr += pattern; |
| if (pattern.charAt(pattern.length - 1) !== '$') |
| regexStr += '$'; |
| regex = new RegExp(regexStr); |
| } |
| else { |
| regexStr = pattern.toString(); |
| regex = pattern; |
| } |
| return (/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { |
| if (isEmptyInputValue(control.value)) { |
| return null; // don't validate empty values to allow optional controls |
| } |
| /** @type {?} */ |
| const value = control.value; |
| return regex.test(value) ? null : |
| { 'pattern': { 'requiredPattern': regexStr, 'actualValue': value } }; |
| }); |
| } |
| /** |
| * \@description |
| * Validator that performs no operation. |
| * @param {?} control |
| * @return {?} |
| */ |
| static nullValidator(control) { return null; } |
| /** |
| * @param {?} validators |
| * @return {?} |
| */ |
| static compose(validators) { |
| if (!validators) |
| return null; |
| /** @type {?} */ |
| const presentValidators = (/** @type {?} */ (validators.filter(isPresent))); |
| if (presentValidators.length == 0) |
| return null; |
| return (/** |
| * @param {?} control |
| * @return {?} |
| */ |
| function (control) { |
| return _mergeErrors(_executeValidators(control, presentValidators)); |
| }); |
| } |
| /** |
| * \@description |
| * Compose multiple async validators into a single function that returns the union |
| * of the individual error objects for the provided control. |
| * |
| * @param {?} validators |
| * @return {?} A validator function that returns an error map with the |
| * merged error objects of the async validators if the validation check fails, otherwise `null`. |
| */ |
| static composeAsync(validators) { |
| if (!validators) |
| return null; |
| /** @type {?} */ |
| const presentValidators = (/** @type {?} */ (validators.filter(isPresent))); |
| if (presentValidators.length == 0) |
| return null; |
| return (/** |
| * @param {?} control |
| * @return {?} |
| */ |
| function (control) { |
| /** @type {?} */ |
| const observables = _executeAsyncValidators(control, presentValidators).map(toObservable); |
| return forkJoin(observables).pipe(map(_mergeErrors)); |
| }); |
| } |
| } |
| /** |
| * @param {?} o |
| * @return {?} |
| */ |
| function isPresent(o) { |
| return o != null; |
| } |
| /** |
| * @param {?} r |
| * @return {?} |
| */ |
| function toObservable(r) { |
| /** @type {?} */ |
| const obs = ɵisPromise(r) ? from(r) : r; |
| if (!(ɵisObservable(obs))) { |
| throw new Error(`Expected validator to return Promise or Observable.`); |
| } |
| return obs; |
| } |
| /** |
| * @param {?} control |
| * @param {?} validators |
| * @return {?} |
| */ |
| function _executeValidators(control, validators) { |
| return validators.map((/** |
| * @param {?} v |
| * @return {?} |
| */ |
| v => v(control))); |
| } |
| /** |
| * @param {?} control |
| * @param {?} validators |
| * @return {?} |
| */ |
| function _executeAsyncValidators(control, validators) { |
| return validators.map((/** |
| * @param {?} v |
| * @return {?} |
| */ |
| v => v(control))); |
| } |
| /** |
| * @param {?} arrayOfErrors |
| * @return {?} |
| */ |
| function _mergeErrors(arrayOfErrors) { |
| /** @type {?} */ |
| const res = arrayOfErrors.reduce((/** |
| * @param {?} res |
| * @param {?} errors |
| * @return {?} |
| */ |
| (res, errors) => { |
| return errors != null ? Object.assign({}, (/** @type {?} */ (res)), errors) : (/** @type {?} */ (res)); |
| }), {}); |
| return Object.keys(res).length === 0 ? null : res; |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * @license |
| * Copyright Google Inc. All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** |
| * @param {?} validator |
| * @return {?} |
| */ |
| function normalizeValidator(validator) { |
| if (((/** @type {?} */ (validator))).validate) { |
| return (/** |
| * @param {?} c |
| * @return {?} |
| */ |
| (c) => ((/** @type {?} */ (validator))).validate(c)); |
| } |
| else { |
| return (/** @type {?} */ (validator)); |
| } |
| } |
| /** |
| * @param {?} validator |
| * @return {?} |
| */ |
| function normalizeAsyncValidator(validator) { |
| if (((/** @type {?} */ (validator))).validate) { |
| return (/** |
| * @param {?} c |
| * @return {?} |
| */ |
| (c) => ((/** @type {?} */ (validator))).validate(c)); |
| } |
| else { |
| return (/** @type {?} */ (validator)); |
| } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const NUMBER_VALUE_ACCESSOR = { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => NumberValueAccessor)), |
| multi: true |
| }; |
| /** |
| * \@description |
| * The `ControlValueAccessor` for writing a number value and listening to number input changes. |
| * The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel` |
| * directives. |
| * |
| * \@usageNotes |
| * |
| * ### Using a number input with a reactive form. |
| * |
| * The following example shows how to use a number input with a reactive form. |
| * |
| * ```ts |
| * const totalCountControl = new FormControl(); |
| * ``` |
| * |
| * ``` |
| * <input type="number" [formControl]="totalCountControl"> |
| * ``` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NumberValueAccessor { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| */ |
| constructor(_renderer, _elementRef) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| /** |
| * \@description |
| * The registered callback function called when a change or input event occurs on the input |
| * element. |
| */ |
| this.onChange = (/** |
| * @param {?} _ |
| * @return {?} |
| */ |
| (_) => { }); |
| /** |
| * \@description |
| * The registered callback function called when a blur event occurs on the input element. |
| */ |
| this.onTouched = (/** |
| * @return {?} |
| */ |
| () => { }); |
| } |
| /** |
| * Sets the "value" property on the input element. |
| * |
| * @param {?} value The checked value |
| * @return {?} |
| */ |
| writeValue(value) { |
| // The value needs to be normalized for IE9, otherwise it is set to 'null' when null |
| /** @type {?} */ |
| const normalizedValue = value == null ? '' : value; |
| this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control value changes. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnChange(fn) { |
| this.onChange = (/** |
| * @param {?} value |
| * @return {?} |
| */ |
| (value) => { fn(value == '' ? null : parseFloat(value)); }); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control is touched. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnTouched(fn) { this.onTouched = fn; } |
| /** |
| * Sets the "disabled" property on the input element. |
| * |
| * @param {?} isDisabled The disabled value |
| * @return {?} |
| */ |
| setDisabledState(isDisabled) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); |
| } |
| } |
| NumberValueAccessor.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]', |
| host: { |
| '(change)': 'onChange($event.target.value)', |
| '(input)': 'onChange($event.target.value)', |
| '(blur)': 'onTouched()' |
| }, |
| providers: [NUMBER_VALUE_ACCESSOR] |
| },] } |
| ]; |
| /** @nocollapse */ |
| NumberValueAccessor.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const RADIO_VALUE_ACCESSOR = { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => RadioControlValueAccessor)), |
| multi: true |
| }; |
| /** |
| * \@description |
| * Class used by Angular to track radio buttons. For internal use only. |
| */ |
| class RadioControlRegistry { |
| constructor() { |
| this._accessors = []; |
| } |
| /** |
| * \@description |
| * Adds a control to the internal registry. For internal use only. |
| * @param {?} control |
| * @param {?} accessor |
| * @return {?} |
| */ |
| add(control, accessor) { |
| this._accessors.push([control, accessor]); |
| } |
| /** |
| * \@description |
| * Removes a control from the internal registry. For internal use only. |
| * @param {?} accessor |
| * @return {?} |
| */ |
| remove(accessor) { |
| for (let i = this._accessors.length - 1; i >= 0; --i) { |
| if (this._accessors[i][1] === accessor) { |
| this._accessors.splice(i, 1); |
| return; |
| } |
| } |
| } |
| /** |
| * \@description |
| * Selects a radio button. For internal use only. |
| * @param {?} accessor |
| * @return {?} |
| */ |
| select(accessor) { |
| this._accessors.forEach((/** |
| * @param {?} c |
| * @return {?} |
| */ |
| (c) => { |
| if (this._isSameGroup(c, accessor) && c[1] !== accessor) { |
| c[1].fireUncheck(accessor.value); |
| } |
| })); |
| } |
| /** |
| * @private |
| * @param {?} controlPair |
| * @param {?} accessor |
| * @return {?} |
| */ |
| _isSameGroup(controlPair, accessor) { |
| if (!controlPair[0].control) |
| return false; |
| return controlPair[0]._parent === accessor._control._parent && |
| controlPair[1].name === accessor.name; |
| } |
| } |
| RadioControlRegistry.decorators = [ |
| { type: Injectable } |
| ]; |
| /** |
| * \@description |
| * The `ControlValueAccessor` for writing radio control values and listening to radio control |
| * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and |
| * `NgModel` directives. |
| * |
| * \@usageNotes |
| * |
| * ### Using radio buttons with reactive form directives |
| * |
| * The follow example shows how to use radio buttons in a reactive form. When using radio buttons in |
| * a reactive form, radio buttons in the same group should have the same `formControlName`. |
| * Providing a `name` attribute is optional. |
| * |
| * {\@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'} |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class RadioControlValueAccessor { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| * @param {?} _registry |
| * @param {?} _injector |
| */ |
| constructor(_renderer, _elementRef, _registry, _injector) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| this._registry = _registry; |
| this._injector = _injector; |
| /** |
| * \@description |
| * The registered callback function called when a change event occurs on the input element. |
| */ |
| this.onChange = (/** |
| * @return {?} |
| */ |
| () => { }); |
| /** |
| * \@description |
| * The registered callback function called when a blur event occurs on the input element. |
| */ |
| this.onTouched = (/** |
| * @return {?} |
| */ |
| () => { }); |
| } |
| /** |
| * \@description |
| * A lifecycle method called when the directive is initialized. For internal use only. |
| * |
| * @return {?} |
| */ |
| ngOnInit() { |
| this._control = this._injector.get(NgControl); |
| this._checkName(); |
| this._registry.add(this._control, this); |
| } |
| /** |
| * \@description |
| * Lifecycle method called before the directive's instance is destroyed. For internal use only. |
| * |
| * @return {?} |
| */ |
| ngOnDestroy() { this._registry.remove(this); } |
| /** |
| * \@description |
| * Sets the "checked" property value on the radio input element. |
| * |
| * @param {?} value The checked value |
| * @return {?} |
| */ |
| writeValue(value) { |
| this._state = value === this.value; |
| this._renderer.setProperty(this._elementRef.nativeElement, 'checked', this._state); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control value changes. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnChange(fn) { |
| this._fn = fn; |
| this.onChange = (/** |
| * @return {?} |
| */ |
| () => { |
| fn(this.value); |
| this._registry.select(this); |
| }); |
| } |
| /** |
| * Sets the "value" on the radio input element and unchecks it. |
| * |
| * @param {?} value |
| * @return {?} |
| */ |
| fireUncheck(value) { this.writeValue(value); } |
| /** |
| * \@description |
| * Registers a function called when the control is touched. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnTouched(fn) { this.onTouched = fn; } |
| /** |
| * Sets the "disabled" property on the input element. |
| * |
| * @param {?} isDisabled The disabled value |
| * @return {?} |
| */ |
| setDisabledState(isDisabled) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _checkName() { |
| if (this.name && this.formControlName && this.name !== this.formControlName) { |
| this._throwNameError(); |
| } |
| if (!this.name && this.formControlName) |
| this.name = this.formControlName; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _throwNameError() { |
| throw new Error(` |
| If you define both a name and a formControlName attribute on your radio button, their values |
| must match. Ex: <input type="radio" formControlName="food" name="food"> |
| `); |
| } |
| } |
| RadioControlValueAccessor.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]', |
| host: { '(change)': 'onChange()', '(blur)': 'onTouched()' }, |
| providers: [RADIO_VALUE_ACCESSOR] |
| },] } |
| ]; |
| /** @nocollapse */ |
| RadioControlValueAccessor.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef }, |
| { type: RadioControlRegistry }, |
| { type: Injector } |
| ]; |
| RadioControlValueAccessor.propDecorators = { |
| name: [{ type: Input }], |
| formControlName: [{ type: Input }], |
| value: [{ type: Input }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const RANGE_VALUE_ACCESSOR = { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => RangeValueAccessor)), |
| multi: true |
| }; |
| /** |
| * \@description |
| * The `ControlValueAccessor` for writing a range value and listening to range input changes. |
| * The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel` |
| * directives. |
| * |
| * \@usageNotes |
| * |
| * ### Using a range input with a reactive form |
| * |
| * The following example shows how to use a range input with a reactive form. |
| * |
| * ```ts |
| * const ageControl = new FormControl(); |
| * ``` |
| * |
| * ``` |
| * <input type="range" [formControl]="ageControl"> |
| * ``` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class RangeValueAccessor { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| */ |
| constructor(_renderer, _elementRef) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| /** |
| * \@description |
| * The registered callback function called when a change or input event occurs on the input |
| * element. |
| */ |
| this.onChange = (/** |
| * @param {?} _ |
| * @return {?} |
| */ |
| (_) => { }); |
| /** |
| * \@description |
| * The registered callback function called when a blur event occurs on the input element. |
| */ |
| this.onTouched = (/** |
| * @return {?} |
| */ |
| () => { }); |
| } |
| /** |
| * Sets the "value" property on the input element. |
| * |
| * @param {?} value The checked value |
| * @return {?} |
| */ |
| writeValue(value) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'value', parseFloat(value)); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control value changes. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnChange(fn) { |
| this.onChange = (/** |
| * @param {?} value |
| * @return {?} |
| */ |
| (value) => { fn(value == '' ? null : parseFloat(value)); }); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control is touched. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnTouched(fn) { this.onTouched = fn; } |
| /** |
| * Sets the "disabled" property on the range input element. |
| * |
| * @param {?} isDisabled The disabled value |
| * @return {?} |
| */ |
| setDisabledState(isDisabled) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); |
| } |
| } |
| RangeValueAccessor.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]', |
| host: { |
| '(change)': 'onChange($event.target.value)', |
| '(input)': 'onChange($event.target.value)', |
| '(blur)': 'onTouched()' |
| }, |
| providers: [RANGE_VALUE_ACCESSOR] |
| },] } |
| ]; |
| /** @nocollapse */ |
| RangeValueAccessor.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * @license |
| * Copyright Google Inc. All Rights Reserved. |
| * |
| * Use of this source code is governed by an MIT-style license that can be |
| * found in the LICENSE file at https://angular.io/license |
| */ |
| /** @type {?} */ |
| const FormErrorExamples = { |
| formControlName: ` |
| <div [formGroup]="myGroup"> |
| <input formControlName="firstName"> |
| </div> |
| |
| In your class: |
| |
| this.myGroup = new FormGroup({ |
| firstName: new FormControl() |
| });`, |
| formGroupName: ` |
| <div [formGroup]="myGroup"> |
| <div formGroupName="person"> |
| <input formControlName="firstName"> |
| </div> |
| </div> |
| |
| In your class: |
| |
| this.myGroup = new FormGroup({ |
| person: new FormGroup({ firstName: new FormControl() }) |
| });`, |
| formArrayName: ` |
| <div [formGroup]="myGroup"> |
| <div formArrayName="cities"> |
| <div *ngFor="let city of cityArray.controls; index as i"> |
| <input [formControlName]="i"> |
| </div> |
| </div> |
| </div> |
| |
| In your class: |
| |
| this.cityArray = new FormArray([new FormControl('SF')]); |
| this.myGroup = new FormGroup({ |
| cities: this.cityArray |
| });`, |
| ngModelGroup: ` |
| <form> |
| <div ngModelGroup="person"> |
| <input [(ngModel)]="person.name" name="firstName"> |
| </div> |
| </form>`, |
| ngModelWithFormGroup: ` |
| <div [formGroup]="myGroup"> |
| <input formControlName="firstName"> |
| <input [(ngModel)]="showMoreControls" [ngModelOptions]="{standalone: true}"> |
| </div> |
| ` |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| class ReactiveErrors { |
| /** |
| * @return {?} |
| */ |
| static controlParentException() { |
| throw new Error(`formControlName must be used with a parent formGroup directive. You'll want to add a formGroup |
| directive and pass it an existing FormGroup instance (you can create one in your class). |
| |
| Example: |
| |
| ${FormErrorExamples.formControlName}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static ngModelGroupException() { |
| throw new Error(`formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents |
| that also have a "form" prefix: formGroupName, formArrayName, or formGroup. |
| |
| Option 1: Update the parent to be formGroupName (reactive form strategy) |
| |
| ${FormErrorExamples.formGroupName} |
| |
| Option 2: Use ngModel instead of formControlName (template-driven strategy) |
| |
| ${FormErrorExamples.ngModelGroup}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static missingFormException() { |
| throw new Error(`formGroup expects a FormGroup instance. Please pass one in. |
| |
| Example: |
| |
| ${FormErrorExamples.formControlName}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static groupParentException() { |
| throw new Error(`formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup |
| directive and pass it an existing FormGroup instance (you can create one in your class). |
| |
| Example: |
| |
| ${FormErrorExamples.formGroupName}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static arrayParentException() { |
| throw new Error(`formArrayName must be used with a parent formGroup directive. You'll want to add a formGroup |
| directive and pass it an existing FormGroup instance (you can create one in your class). |
| |
| Example: |
| |
| ${FormErrorExamples.formArrayName}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static disabledAttrWarning() { |
| console.warn(` |
| It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true |
| when you set up this control in your component class, the disabled attribute will actually be set in the DOM for |
| you. We recommend using this approach to avoid 'changed after checked' errors. |
| |
| Example: |
| form = new FormGroup({ |
| first: new FormControl({value: 'Nancy', disabled: true}, Validators.required), |
| last: new FormControl('Drew', Validators.required) |
| }); |
| `); |
| } |
| /** |
| * @param {?} directiveName |
| * @return {?} |
| */ |
| static ngModelWarning(directiveName) { |
| console.warn(` |
| It looks like you're using ngModel on the same form field as ${directiveName}. |
| Support for using the ngModel input property and ngModelChange event with |
| reactive form directives has been deprecated in Angular v6 and will be removed |
| in Angular v7. |
| |
| For more information on this, see our API docs here: |
| https://angular.io/api/forms/${directiveName === 'formControl' ? 'FormControlDirective' |
| : 'FormControlName'}#use-with-ngmodel |
| `); |
| } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const SELECT_VALUE_ACCESSOR = { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => SelectControlValueAccessor)), |
| multi: true |
| }; |
| /** |
| * @param {?} id |
| * @param {?} value |
| * @return {?} |
| */ |
| function _buildValueString(id, value) { |
| if (id == null) |
| return `${value}`; |
| if (value && typeof value === 'object') |
| value = 'Object'; |
| return `${id}: ${value}`.slice(0, 50); |
| } |
| /** |
| * @param {?} valueString |
| * @return {?} |
| */ |
| function _extractId(valueString) { |
| return valueString.split(':')[0]; |
| } |
| /** |
| * \@description |
| * The `ControlValueAccessor` for writing select control values and listening to select control |
| * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and |
| * `NgModel` directives. |
| * |
| * \@usageNotes |
| * |
| * ### Using select controls in a reactive form |
| * |
| * The following examples show how to use a select control in a reactive form. |
| * |
| * {\@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'} |
| * |
| * ### Using select controls in a template-driven form |
| * |
| * To use a select in a template-driven form, simply add an `ngModel` and a `name` |
| * attribute to the main `<select>` tag. |
| * |
| * {\@example forms/ts/selectControl/select_control_example.ts region='Component'} |
| * |
| * ### Customizing option selection |
| * |
| * Angular uses object identity to select option. It's possible for the identities of items |
| * to change while the data does not. This can happen, for example, if the items are produced |
| * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the |
| * second response will produce objects with different identities. |
| * |
| * To customize the default option comparison algorithm, `<select>` supports `compareWith` input. |
| * `compareWith` takes a **function** which has two arguments: `option1` and `option2`. |
| * If `compareWith` is given, Angular selects option by the return value of the function. |
| * |
| * ```ts |
| * const selectedCountriesControl = new FormControl(); |
| * ``` |
| * |
| * ``` |
| * <select [compareWith]="compareFn" [formControl]="selectedCountriesControl"> |
| * <option *ngFor="let country of countries" [ngValue]="country"> |
| * {{country.name}} |
| * </option> |
| * </select> |
| * |
| * compareFn(c1: Country, c2: Country): boolean { |
| * return c1 && c2 ? c1.id === c2.id : c1 === c2; |
| * } |
| * ``` |
| * |
| * **Note:** We listen to the 'change' event because 'input' events aren't fired |
| * for selects in Firefox and IE: |
| * https://bugzilla.mozilla.org/show_bug.cgi?id=1024350 |
| * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/ |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class SelectControlValueAccessor { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| */ |
| constructor(_renderer, _elementRef) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| /** |
| * \@internal |
| */ |
| this._optionMap = new Map(); |
| /** |
| * \@internal |
| */ |
| this._idCounter = 0; |
| /** |
| * \@description |
| * The registered callback function called when a change event occurs on the input element. |
| */ |
| this.onChange = (/** |
| * @param {?} _ |
| * @return {?} |
| */ |
| (_) => { }); |
| /** |
| * \@description |
| * The registered callback function called when a blur event occurs on the input element. |
| */ |
| this.onTouched = (/** |
| * @return {?} |
| */ |
| () => { }); |
| this._compareWith = ɵlooseIdentical; |
| } |
| /** |
| * \@description |
| * Tracks the option comparison algorithm for tracking identities when |
| * checking for changes. |
| * @param {?} fn |
| * @return {?} |
| */ |
| set compareWith(fn) { |
| if (typeof fn !== 'function') { |
| throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`); |
| } |
| this._compareWith = fn; |
| } |
| /** |
| * Sets the "value" property on the input element. The "selectedIndex" |
| * property is also set if an ID is provided on the option element. |
| * |
| * @param {?} value The checked value |
| * @return {?} |
| */ |
| writeValue(value) { |
| this.value = value; |
| /** @type {?} */ |
| const id = this._getOptionId(value); |
| if (id == null) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1); |
| } |
| /** @type {?} */ |
| const valueString = _buildValueString(id, value); |
| this._renderer.setProperty(this._elementRef.nativeElement, 'value', valueString); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control value changes. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnChange(fn) { |
| this.onChange = (/** |
| * @param {?} valueString |
| * @return {?} |
| */ |
| (valueString) => { |
| this.value = this._getOptionValue(valueString); |
| fn(this.value); |
| }); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control is touched. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnTouched(fn) { this.onTouched = fn; } |
| /** |
| * Sets the "disabled" property on the select input element. |
| * |
| * @param {?} isDisabled The disabled value |
| * @return {?} |
| */ |
| setDisabledState(isDisabled) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _registerOption() { return (this._idCounter++).toString(); } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _getOptionId(value) { |
| for (const id of Array.from(this._optionMap.keys())) { |
| if (this._compareWith(this._optionMap.get(id), value)) |
| return id; |
| } |
| return null; |
| } |
| /** |
| * \@internal |
| * @param {?} valueString |
| * @return {?} |
| */ |
| _getOptionValue(valueString) { |
| /** @type {?} */ |
| const id = _extractId(valueString); |
| return this._optionMap.has(id) ? this._optionMap.get(id) : valueString; |
| } |
| } |
| SelectControlValueAccessor.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]', |
| host: { '(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()' }, |
| providers: [SELECT_VALUE_ACCESSOR] |
| },] } |
| ]; |
| /** @nocollapse */ |
| SelectControlValueAccessor.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef } |
| ]; |
| SelectControlValueAccessor.propDecorators = { |
| compareWith: [{ type: Input }] |
| }; |
| /** |
| * \@description |
| * Marks `<option>` as dynamic, so Angular can be notified when options change. |
| * |
| * @see `SelectControlValueAccessor` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NgSelectOption { |
| /** |
| * @param {?} _element |
| * @param {?} _renderer |
| * @param {?} _select |
| */ |
| constructor(_element, _renderer, _select) { |
| this._element = _element; |
| this._renderer = _renderer; |
| this._select = _select; |
| if (this._select) |
| this.id = this._select._registerOption(); |
| } |
| /** |
| * \@description |
| * Tracks the value bound to the option element. Unlike the value binding, |
| * ngValue supports binding to objects. |
| * @param {?} value |
| * @return {?} |
| */ |
| set ngValue(value) { |
| if (this._select == null) |
| return; |
| this._select._optionMap.set(this.id, value); |
| this._setElementValue(_buildValueString(this.id, value)); |
| this._select.writeValue(this._select.value); |
| } |
| /** |
| * \@description |
| * Tracks simple string values bound to the option element. |
| * For objects, use the `ngValue` input binding. |
| * @param {?} value |
| * @return {?} |
| */ |
| set value(value) { |
| this._setElementValue(value); |
| if (this._select) |
| this._select.writeValue(this._select.value); |
| } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _setElementValue(value) { |
| this._renderer.setProperty(this._element.nativeElement, 'value', value); |
| } |
| /** |
| * \@description |
| * Lifecycle method called before the directive's instance is destroyed. For internal use only. |
| * @return {?} |
| */ |
| ngOnDestroy() { |
| if (this._select) { |
| this._select._optionMap.delete(this.id); |
| this._select.writeValue(this._select.value); |
| } |
| } |
| } |
| NgSelectOption.decorators = [ |
| { type: Directive, args: [{ selector: 'option' },] } |
| ]; |
| /** @nocollapse */ |
| NgSelectOption.ctorParameters = () => [ |
| { type: ElementRef }, |
| { type: Renderer2 }, |
| { type: SelectControlValueAccessor, decorators: [{ type: Optional }, { type: Host }] } |
| ]; |
| NgSelectOption.propDecorators = { |
| ngValue: [{ type: Input, args: ['ngValue',] }], |
| value: [{ type: Input, args: ['value',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const SELECT_MULTIPLE_VALUE_ACCESSOR = { |
| provide: NG_VALUE_ACCESSOR, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => SelectMultipleControlValueAccessor)), |
| multi: true |
| }; |
| /** |
| * @param {?} id |
| * @param {?} value |
| * @return {?} |
| */ |
| function _buildValueString$1(id, value) { |
| if (id == null) |
| return `${value}`; |
| if (typeof value === 'string') |
| value = `'${value}'`; |
| if (value && typeof value === 'object') |
| value = 'Object'; |
| return `${id}: ${value}`.slice(0, 50); |
| } |
| /** |
| * @param {?} valueString |
| * @return {?} |
| */ |
| function _extractId$1(valueString) { |
| return valueString.split(':')[0]; |
| } |
| /** |
| * \@description |
| * The `ControlValueAccessor` for writing multi-select control values and listening to multi-select control |
| * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel` |
| * directives. |
| * |
| * @see `SelectControlValueAccessor` |
| * |
| * \@usageNotes |
| * |
| * ### Using a multi-select control |
| * |
| * The follow example shows you how to use a multi-select control with a reactive form. |
| * |
| * ```ts |
| * const countryControl = new FormControl(); |
| * ``` |
| * |
| * ``` |
| * <select multiple name="countries" [formControl]="countryControl"> |
| * <option *ngFor="let country of countries" [ngValue]="country"> |
| * {{ country.name }} |
| * </option> |
| * </select> |
| * ``` |
| * |
| * ### Customizing option selection |
| * |
| * To customize the default option comparison algorithm, `<select>` supports `compareWith` input. |
| * See the `SelectControlValueAccessor` for usage. |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class SelectMultipleControlValueAccessor { |
| /** |
| * @param {?} _renderer |
| * @param {?} _elementRef |
| */ |
| constructor(_renderer, _elementRef) { |
| this._renderer = _renderer; |
| this._elementRef = _elementRef; |
| /** |
| * \@internal |
| */ |
| this._optionMap = new Map(); |
| /** |
| * \@internal |
| */ |
| this._idCounter = 0; |
| /** |
| * \@description |
| * The registered callback function called when a change event occurs on the input element. |
| */ |
| this.onChange = (/** |
| * @param {?} _ |
| * @return {?} |
| */ |
| (_) => { }); |
| /** |
| * \@description |
| * The registered callback function called when a blur event occurs on the input element. |
| */ |
| this.onTouched = (/** |
| * @return {?} |
| */ |
| () => { }); |
| this._compareWith = ɵlooseIdentical; |
| } |
| /** |
| * \@description |
| * Tracks the option comparison algorithm for tracking identities when |
| * checking for changes. |
| * @param {?} fn |
| * @return {?} |
| */ |
| set compareWith(fn) { |
| if (typeof fn !== 'function') { |
| throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`); |
| } |
| this._compareWith = fn; |
| } |
| /** |
| * \@description |
| * Sets the "value" property on one or of more |
| * of the select's options. |
| * |
| * @param {?} value The value |
| * @return {?} |
| */ |
| writeValue(value) { |
| this.value = value; |
| /** @type {?} */ |
| let optionSelectedStateSetter; |
| if (Array.isArray(value)) { |
| // convert values to ids |
| /** @type {?} */ |
| const ids = value.map((/** |
| * @param {?} v |
| * @return {?} |
| */ |
| (v) => this._getOptionId(v))); |
| optionSelectedStateSetter = (/** |
| * @param {?} opt |
| * @param {?} o |
| * @return {?} |
| */ |
| (opt, o) => { opt._setSelected(ids.indexOf(o.toString()) > -1); }); |
| } |
| else { |
| optionSelectedStateSetter = (/** |
| * @param {?} opt |
| * @param {?} o |
| * @return {?} |
| */ |
| (opt, o) => { opt._setSelected(false); }); |
| } |
| this._optionMap.forEach(optionSelectedStateSetter); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control value changes |
| * and writes an array of the selected options. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnChange(fn) { |
| this.onChange = (/** |
| * @param {?} _ |
| * @return {?} |
| */ |
| (_) => { |
| /** @type {?} */ |
| const selected = []; |
| if (_.hasOwnProperty('selectedOptions')) { |
| /** @type {?} */ |
| const options = _.selectedOptions; |
| for (let i = 0; i < options.length; i++) { |
| /** @type {?} */ |
| const opt = options.item(i); |
| /** @type {?} */ |
| const val = this._getOptionValue(opt.value); |
| selected.push(val); |
| } |
| } |
| // Degrade on IE |
| else { |
| /** @type {?} */ |
| const options = (/** @type {?} */ (_.options)); |
| for (let i = 0; i < options.length; i++) { |
| /** @type {?} */ |
| const opt = options.item(i); |
| if (opt.selected) { |
| /** @type {?} */ |
| const val = this._getOptionValue(opt.value); |
| selected.push(val); |
| } |
| } |
| } |
| this.value = selected; |
| fn(selected); |
| }); |
| } |
| /** |
| * \@description |
| * Registers a function called when the control is touched. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnTouched(fn) { this.onTouched = fn; } |
| /** |
| * Sets the "disabled" property on the select input element. |
| * |
| * @param {?} isDisabled The disabled value |
| * @return {?} |
| */ |
| setDisabledState(isDisabled) { |
| this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); |
| } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _registerOption(value) { |
| /** @type {?} */ |
| const id = (this._idCounter++).toString(); |
| this._optionMap.set(id, value); |
| return id; |
| } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _getOptionId(value) { |
| for (const id of Array.from(this._optionMap.keys())) { |
| if (this._compareWith((/** @type {?} */ (this._optionMap.get(id)))._value, value)) |
| return id; |
| } |
| return null; |
| } |
| /** |
| * \@internal |
| * @param {?} valueString |
| * @return {?} |
| */ |
| _getOptionValue(valueString) { |
| /** @type {?} */ |
| const id = _extractId$1(valueString); |
| return this._optionMap.has(id) ? (/** @type {?} */ (this._optionMap.get(id)))._value : valueString; |
| } |
| } |
| SelectMultipleControlValueAccessor.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]', |
| host: { '(change)': 'onChange($event.target)', '(blur)': 'onTouched()' }, |
| providers: [SELECT_MULTIPLE_VALUE_ACCESSOR] |
| },] } |
| ]; |
| /** @nocollapse */ |
| SelectMultipleControlValueAccessor.ctorParameters = () => [ |
| { type: Renderer2 }, |
| { type: ElementRef } |
| ]; |
| SelectMultipleControlValueAccessor.propDecorators = { |
| compareWith: [{ type: Input }] |
| }; |
| /** |
| * \@description |
| * Marks `<option>` as dynamic, so Angular can be notified when options change. |
| * |
| * @see `SelectMultipleControlValueAccessor` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class ɵNgSelectMultipleOption { |
| /** |
| * @param {?} _element |
| * @param {?} _renderer |
| * @param {?} _select |
| */ |
| constructor(_element, _renderer, _select) { |
| this._element = _element; |
| this._renderer = _renderer; |
| this._select = _select; |
| if (this._select) { |
| this.id = this._select._registerOption(this); |
| } |
| } |
| /** |
| * \@description |
| * Tracks the value bound to the option element. Unlike the value binding, |
| * ngValue supports binding to objects. |
| * @param {?} value |
| * @return {?} |
| */ |
| set ngValue(value) { |
| if (this._select == null) |
| return; |
| this._value = value; |
| this._setElementValue(_buildValueString$1(this.id, value)); |
| this._select.writeValue(this._select.value); |
| } |
| /** |
| * \@description |
| * Tracks simple string values bound to the option element. |
| * For objects, use the `ngValue` input binding. |
| * @param {?} value |
| * @return {?} |
| */ |
| set value(value) { |
| if (this._select) { |
| this._value = value; |
| this._setElementValue(_buildValueString$1(this.id, value)); |
| this._select.writeValue(this._select.value); |
| } |
| else { |
| this._setElementValue(value); |
| } |
| } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _setElementValue(value) { |
| this._renderer.setProperty(this._element.nativeElement, 'value', value); |
| } |
| /** |
| * \@internal |
| * @param {?} selected |
| * @return {?} |
| */ |
| _setSelected(selected) { |
| this._renderer.setProperty(this._element.nativeElement, 'selected', selected); |
| } |
| /** |
| * \@description |
| * Lifecycle method called before the directive's instance is destroyed. For internal use only. |
| * @return {?} |
| */ |
| ngOnDestroy() { |
| if (this._select) { |
| this._select._optionMap.delete(this.id); |
| this._select.writeValue(this._select.value); |
| } |
| } |
| } |
| ɵNgSelectMultipleOption.decorators = [ |
| { type: Directive, args: [{ selector: 'option' },] } |
| ]; |
| /** @nocollapse */ |
| ɵNgSelectMultipleOption.ctorParameters = () => [ |
| { type: ElementRef }, |
| { type: Renderer2 }, |
| { type: SelectMultipleControlValueAccessor, decorators: [{ type: Optional }, { type: Host }] } |
| ]; |
| ɵNgSelectMultipleOption.propDecorators = { |
| ngValue: [{ type: Input, args: ['ngValue',] }], |
| value: [{ type: Input, args: ['value',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * @param {?} name |
| * @param {?} parent |
| * @return {?} |
| */ |
| function controlPath(name, parent) { |
| return [...(/** @type {?} */ (parent.path)), name]; |
| } |
| /** |
| * @param {?} control |
| * @param {?} dir |
| * @return {?} |
| */ |
| function setUpControl(control, dir) { |
| if (!control) |
| _throwError(dir, 'Cannot find control with'); |
| if (!dir.valueAccessor) |
| _throwError(dir, 'No value accessor for form control with'); |
| control.validator = Validators.compose([(/** @type {?} */ (control.validator)), dir.validator]); |
| control.asyncValidator = Validators.composeAsync([(/** @type {?} */ (control.asyncValidator)), dir.asyncValidator]); |
| (/** @type {?} */ (dir.valueAccessor)).writeValue(control.value); |
| setUpViewChangePipeline(control, dir); |
| setUpModelChangePipeline(control, dir); |
| setUpBlurPipeline(control, dir); |
| if ((/** @type {?} */ (dir.valueAccessor)).setDisabledState) { |
| control.registerOnDisabledChange((/** |
| * @param {?} isDisabled |
| * @return {?} |
| */ |
| (isDisabled) => { (/** @type {?} */ ((/** @type {?} */ (dir.valueAccessor)).setDisabledState))(isDisabled); })); |
| } |
| // re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4 |
| dir._rawValidators.forEach((/** |
| * @param {?} validator |
| * @return {?} |
| */ |
| (validator) => { |
| if (((/** @type {?} */ (validator))).registerOnValidatorChange) |
| (/** @type {?} */ (((/** @type {?} */ (validator))).registerOnValidatorChange))((/** |
| * @return {?} |
| */ |
| () => control.updateValueAndValidity())); |
| })); |
| dir._rawAsyncValidators.forEach((/** |
| * @param {?} validator |
| * @return {?} |
| */ |
| (validator) => { |
| if (((/** @type {?} */ (validator))).registerOnValidatorChange) |
| (/** @type {?} */ (((/** @type {?} */ (validator))).registerOnValidatorChange))((/** |
| * @return {?} |
| */ |
| () => control.updateValueAndValidity())); |
| })); |
| } |
| /** |
| * @param {?} control |
| * @param {?} dir |
| * @return {?} |
| */ |
| function cleanUpControl(control, dir) { |
| (/** @type {?} */ (dir.valueAccessor)).registerOnChange((/** |
| * @return {?} |
| */ |
| () => _noControlError(dir))); |
| (/** @type {?} */ (dir.valueAccessor)).registerOnTouched((/** |
| * @return {?} |
| */ |
| () => _noControlError(dir))); |
| dir._rawValidators.forEach((/** |
| * @param {?} validator |
| * @return {?} |
| */ |
| (validator) => { |
| if (validator.registerOnValidatorChange) { |
| validator.registerOnValidatorChange(null); |
| } |
| })); |
| dir._rawAsyncValidators.forEach((/** |
| * @param {?} validator |
| * @return {?} |
| */ |
| (validator) => { |
| if (validator.registerOnValidatorChange) { |
| validator.registerOnValidatorChange(null); |
| } |
| })); |
| if (control) |
| control._clearChangeFns(); |
| } |
| /** |
| * @param {?} control |
| * @param {?} dir |
| * @return {?} |
| */ |
| function setUpViewChangePipeline(control, dir) { |
| (/** @type {?} */ (dir.valueAccessor)).registerOnChange((/** |
| * @param {?} newValue |
| * @return {?} |
| */ |
| (newValue) => { |
| control._pendingValue = newValue; |
| control._pendingChange = true; |
| control._pendingDirty = true; |
| if (control.updateOn === 'change') |
| updateControl(control, dir); |
| })); |
| } |
| /** |
| * @param {?} control |
| * @param {?} dir |
| * @return {?} |
| */ |
| function setUpBlurPipeline(control, dir) { |
| (/** @type {?} */ (dir.valueAccessor)).registerOnTouched((/** |
| * @return {?} |
| */ |
| () => { |
| control._pendingTouched = true; |
| if (control.updateOn === 'blur' && control._pendingChange) |
| updateControl(control, dir); |
| if (control.updateOn !== 'submit') |
| control.markAsTouched(); |
| })); |
| } |
| /** |
| * @param {?} control |
| * @param {?} dir |
| * @return {?} |
| */ |
| function updateControl(control, dir) { |
| if (control._pendingDirty) |
| control.markAsDirty(); |
| control.setValue(control._pendingValue, { emitModelToViewChange: false }); |
| dir.viewToModelUpdate(control._pendingValue); |
| control._pendingChange = false; |
| } |
| /** |
| * @param {?} control |
| * @param {?} dir |
| * @return {?} |
| */ |
| function setUpModelChangePipeline(control, dir) { |
| control.registerOnChange((/** |
| * @param {?} newValue |
| * @param {?} emitModelEvent |
| * @return {?} |
| */ |
| (newValue, emitModelEvent) => { |
| // control -> view |
| (/** @type {?} */ (dir.valueAccessor)).writeValue(newValue); |
| // control -> ngModel |
| if (emitModelEvent) |
| dir.viewToModelUpdate(newValue); |
| })); |
| } |
| /** |
| * @param {?} control |
| * @param {?} dir |
| * @return {?} |
| */ |
| function setUpFormContainer(control, dir) { |
| if (control == null) |
| _throwError(dir, 'Cannot find control with'); |
| control.validator = Validators.compose([control.validator, dir.validator]); |
| control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]); |
| } |
| /** |
| * @param {?} dir |
| * @return {?} |
| */ |
| function _noControlError(dir) { |
| return _throwError(dir, 'There is no FormControl instance attached to form control element with'); |
| } |
| /** |
| * @param {?} dir |
| * @param {?} message |
| * @return {?} |
| */ |
| function _throwError(dir, message) { |
| /** @type {?} */ |
| let messageEnd; |
| if ((/** @type {?} */ (dir.path)).length > 1) { |
| messageEnd = `path: '${(/** @type {?} */ (dir.path)).join(' -> ')}'`; |
| } |
| else if ((/** @type {?} */ (dir.path))[0]) { |
| messageEnd = `name: '${dir.path}'`; |
| } |
| else { |
| messageEnd = 'unspecified name attribute'; |
| } |
| throw new Error(`${message} ${messageEnd}`); |
| } |
| /** |
| * @param {?} validators |
| * @return {?} |
| */ |
| function composeValidators(validators) { |
| return validators != null ? Validators.compose(validators.map(normalizeValidator)) : null; |
| } |
| /** |
| * @param {?} validators |
| * @return {?} |
| */ |
| function composeAsyncValidators(validators) { |
| return validators != null ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) : |
| null; |
| } |
| /** |
| * @param {?} changes |
| * @param {?} viewModel |
| * @return {?} |
| */ |
| function isPropertyUpdated(changes, viewModel) { |
| if (!changes.hasOwnProperty('model')) |
| return false; |
| /** @type {?} */ |
| const change = changes['model']; |
| if (change.isFirstChange()) |
| return true; |
| return !ɵlooseIdentical(viewModel, change.currentValue); |
| } |
| /** @type {?} */ |
| const BUILTIN_ACCESSORS = [ |
| CheckboxControlValueAccessor, |
| RangeValueAccessor, |
| NumberValueAccessor, |
| SelectControlValueAccessor, |
| SelectMultipleControlValueAccessor, |
| RadioControlValueAccessor, |
| ]; |
| /** |
| * @param {?} valueAccessor |
| * @return {?} |
| */ |
| function isBuiltInAccessor(valueAccessor) { |
| return BUILTIN_ACCESSORS.some((/** |
| * @param {?} a |
| * @return {?} |
| */ |
| a => valueAccessor.constructor === a)); |
| } |
| /** |
| * @param {?} form |
| * @param {?} directives |
| * @return {?} |
| */ |
| function syncPendingControls(form, directives) { |
| form._syncPendingControls(); |
| directives.forEach((/** |
| * @param {?} dir |
| * @return {?} |
| */ |
| dir => { |
| /** @type {?} */ |
| const control = (/** @type {?} */ (dir.control)); |
| if (control.updateOn === 'submit' && control._pendingChange) { |
| dir.viewToModelUpdate(control._pendingValue); |
| control._pendingChange = false; |
| } |
| })); |
| } |
| // TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented |
| /** |
| * @param {?} dir |
| * @param {?} valueAccessors |
| * @return {?} |
| */ |
| function selectValueAccessor(dir, valueAccessors) { |
| if (!valueAccessors) |
| return null; |
| if (!Array.isArray(valueAccessors)) |
| _throwError(dir, 'Value accessor was not provided as an array for form control with'); |
| /** @type {?} */ |
| let defaultAccessor = undefined; |
| /** @type {?} */ |
| let builtinAccessor = undefined; |
| /** @type {?} */ |
| let customAccessor = undefined; |
| valueAccessors.forEach((/** |
| * @param {?} v |
| * @return {?} |
| */ |
| (v) => { |
| if (v.constructor === DefaultValueAccessor) { |
| defaultAccessor = v; |
| } |
| else if (isBuiltInAccessor(v)) { |
| if (builtinAccessor) |
| _throwError(dir, 'More than one built-in value accessor matches form control with'); |
| builtinAccessor = v; |
| } |
| else { |
| if (customAccessor) |
| _throwError(dir, 'More than one custom value accessor matches form control with'); |
| customAccessor = v; |
| } |
| })); |
| if (customAccessor) |
| return customAccessor; |
| if (builtinAccessor) |
| return builtinAccessor; |
| if (defaultAccessor) |
| return defaultAccessor; |
| _throwError(dir, 'No valid value accessor for form control with'); |
| return null; |
| } |
| /** |
| * @template T |
| * @param {?} list |
| * @param {?} el |
| * @return {?} |
| */ |
| function removeDir(list, el) { |
| /** @type {?} */ |
| const index = list.indexOf(el); |
| if (index > -1) |
| list.splice(index, 1); |
| } |
| // TODO(kara): remove after deprecation period |
| /** |
| * @param {?} name |
| * @param {?} type |
| * @param {?} instance |
| * @param {?} warningConfig |
| * @return {?} |
| */ |
| function _ngModelWarning(name, type, instance, warningConfig) { |
| if (!isDevMode() || warningConfig === 'never') |
| return; |
| if (((warningConfig === null || warningConfig === 'once') && !type._ngModelWarningSentOnce) || |
| (warningConfig === 'always' && !instance._ngModelWarningSent)) { |
| ReactiveErrors.ngModelWarning(name); |
| type._ngModelWarningSentOnce = true; |
| instance._ngModelWarningSent = true; |
| } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * Reports that a FormControl is valid, meaning that no errors exist in the input value. |
| * |
| * @see `status` |
| * @type {?} |
| */ |
| const VALID = 'VALID'; |
| /** |
| * Reports that a FormControl is invalid, meaning that an error exists in the input value. |
| * |
| * @see `status` |
| * @type {?} |
| */ |
| const INVALID = 'INVALID'; |
| /** |
| * Reports that a FormControl is pending, meaning that that async validation is occurring and |
| * errors are not yet available for the input value. |
| * |
| * @see `markAsPending` |
| * @see `status` |
| * @type {?} |
| */ |
| const PENDING = 'PENDING'; |
| /** |
| * Reports that a FormControl is disabled, meaning that the control is exempt from ancestor |
| * calculations of validity or value. |
| * |
| * @see `markAsDisabled` |
| * @see `status` |
| * @type {?} |
| */ |
| const DISABLED = 'DISABLED'; |
| /** |
| * @param {?} control |
| * @param {?} path |
| * @param {?} delimiter |
| * @return {?} |
| */ |
| function _find(control, path, delimiter) { |
| if (path == null) |
| return null; |
| if (!(path instanceof Array)) { |
| path = ((/** @type {?} */ (path))).split(delimiter); |
| } |
| if (path instanceof Array && (path.length === 0)) |
| return null; |
| return ((/** @type {?} */ (path))).reduce((/** |
| * @param {?} v |
| * @param {?} name |
| * @return {?} |
| */ |
| (v, name) => { |
| if (v instanceof FormGroup) { |
| return v.controls.hasOwnProperty((/** @type {?} */ (name))) ? v.controls[name] : null; |
| } |
| if (v instanceof FormArray) { |
| return v.at((/** @type {?} */ (name))) || null; |
| } |
| return null; |
| }), control); |
| } |
| /** |
| * @param {?=} validatorOrOpts |
| * @return {?} |
| */ |
| function coerceToValidator(validatorOrOpts) { |
| /** @type {?} */ |
| const validator = (/** @type {?} */ ((isOptionsObj(validatorOrOpts) ? ((/** @type {?} */ (validatorOrOpts))).validators : |
| validatorOrOpts))); |
| return Array.isArray(validator) ? composeValidators(validator) : validator || null; |
| } |
| /** |
| * @param {?=} asyncValidator |
| * @param {?=} validatorOrOpts |
| * @return {?} |
| */ |
| function coerceToAsyncValidator(asyncValidator, validatorOrOpts) { |
| /** @type {?} */ |
| const origAsyncValidator = (/** @type {?} */ ((isOptionsObj(validatorOrOpts) ? ((/** @type {?} */ (validatorOrOpts))).asyncValidators : |
| asyncValidator))); |
| return Array.isArray(origAsyncValidator) ? composeAsyncValidators(origAsyncValidator) : |
| origAsyncValidator || null; |
| } |
| /** |
| * @param {?=} validatorOrOpts |
| * @return {?} |
| */ |
| function isOptionsObj(validatorOrOpts) { |
| return validatorOrOpts != null && !Array.isArray(validatorOrOpts) && |
| typeof validatorOrOpts === 'object'; |
| } |
| /** |
| * This is the base class for `FormControl`, `FormGroup`, and `FormArray`. |
| * |
| * It provides some of the shared behavior that all controls and groups of controls have, like |
| * running validators, calculating status, and resetting state. It also defines the properties |
| * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be |
| * instantiated directly. |
| * |
| * @see [Forms Guide](/guide/forms) |
| * @see [Reactive Forms Guide](/guide/reactive-forms) |
| * @see [Dynamic Forms Guide](/guide/dynamic-form) |
| * |
| * \@publicApi |
| * @abstract |
| */ |
| class AbstractControl { |
| /** |
| * Initialize the AbstractControl instance. |
| * |
| * @param {?} validator The function that determines the synchronous validity of this control. |
| * @param {?} asyncValidator The function that determines the asynchronous validity of this |
| * control. |
| */ |
| constructor(validator, asyncValidator) { |
| this.validator = validator; |
| this.asyncValidator = asyncValidator; |
| /** |
| * \@internal |
| */ |
| this._onCollectionChange = (/** |
| * @return {?} |
| */ |
| () => { }); |
| /** |
| * A control is `pristine` if the user has not yet changed |
| * the value in the UI. |
| * |
| * @return True if the user has not yet changed the value in the UI; compare `dirty`. |
| * Programmatic changes to a control's value do not mark it dirty. |
| */ |
| this.pristine = true; |
| /** |
| * True if the control is marked as `touched`. |
| * |
| * A control is marked `touched` once the user has triggered |
| * a `blur` event on it. |
| */ |
| this.touched = false; |
| /** |
| * \@internal |
| */ |
| this._onDisabledChange = []; |
| } |
| /** |
| * The parent control. |
| * @return {?} |
| */ |
| get parent() { return this._parent; } |
| /** |
| * A control is `valid` when its `status` is `VALID`. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @return {?} True if the control has passed all of its validation tests, |
| * false otherwise. |
| */ |
| get valid() { return this.status === VALID; } |
| /** |
| * A control is `invalid` when its `status` is `INVALID`. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @return {?} True if this control has failed one or more of its validation checks, |
| * false otherwise. |
| */ |
| get invalid() { return this.status === INVALID; } |
| /** |
| * A control is `pending` when its `status` is `PENDING`. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @return {?} True if this control is in the process of conducting a validation check, |
| * false otherwise. |
| */ |
| get pending() { return this.status == PENDING; } |
| /** |
| * A control is `disabled` when its `status` is `DISABLED`. |
| * |
| * Disabled controls are exempt from validation checks and |
| * are not included in the aggregate value of their ancestor |
| * controls. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @return {?} True if the control is disabled, false otherwise. |
| */ |
| get disabled() { return this.status === DISABLED; } |
| /** |
| * A control is `enabled` as long as its `status` is not `DISABLED`. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @return {?} True if the control has any status other than 'DISABLED', |
| * false if the status is 'DISABLED'. |
| * |
| */ |
| get enabled() { return this.status !== DISABLED; } |
| /** |
| * A control is `dirty` if the user has changed the value |
| * in the UI. |
| * |
| * @return {?} True if the user has changed the value of this control in the UI; compare `pristine`. |
| * Programmatic changes to a control's value do not mark it dirty. |
| */ |
| get dirty() { return !this.pristine; } |
| /** |
| * True if the control has not been marked as touched |
| * |
| * A control is `untouched` if the user has not yet triggered |
| * a `blur` event on it. |
| * @return {?} |
| */ |
| get untouched() { return !this.touched; } |
| /** |
| * Reports the update strategy of the `AbstractControl` (meaning |
| * the event on which the control updates itself). |
| * Possible values: `'change'` | `'blur'` | `'submit'` |
| * Default value: `'change'` |
| * @return {?} |
| */ |
| get updateOn() { |
| return this._updateOn ? this._updateOn : (this.parent ? this.parent.updateOn : 'change'); |
| } |
| /** |
| * Sets the synchronous validators that are active on this control. Calling |
| * this overwrites any existing sync validators. |
| * @param {?} newValidator |
| * @return {?} |
| */ |
| setValidators(newValidator) { |
| this.validator = coerceToValidator(newValidator); |
| } |
| /** |
| * Sets the async validators that are active on this control. Calling this |
| * overwrites any existing async validators. |
| * @param {?} newValidator |
| * @return {?} |
| */ |
| setAsyncValidators(newValidator) { |
| this.asyncValidator = coerceToAsyncValidator(newValidator); |
| } |
| /** |
| * Empties out the sync validator list. |
| * @return {?} |
| */ |
| clearValidators() { this.validator = null; } |
| /** |
| * Empties out the async validator list. |
| * @return {?} |
| */ |
| clearAsyncValidators() { this.asyncValidator = null; } |
| /** |
| * Marks the control as `touched`. A control is touched by focus and |
| * blur events that do not change the value. |
| * |
| * @see `markAsUntouched()` / `markAsDirty()` / `markAsPristine()` |
| * |
| * @param {?=} opts Configuration options that determine how the control propagates changes |
| * and emits events events after marking is applied. |
| * * `onlySelf`: When true, mark only this control. When false or not supplied, |
| * marks all direct ancestors. Default is false. |
| * @return {?} |
| */ |
| markAsTouched(opts = {}) { |
| ((/** @type {?} */ (this))).touched = true; |
| if (this._parent && !opts.onlySelf) { |
| this._parent.markAsTouched(opts); |
| } |
| } |
| /** |
| * Marks the control and all its descendant controls as `touched`. |
| * @see `markAsTouched()` |
| * @return {?} |
| */ |
| markAllAsTouched() { |
| this.markAsTouched({ onlySelf: true }); |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control.markAllAsTouched())); |
| } |
| /** |
| * Marks the control as `untouched`. |
| * |
| * If the control has any children, also marks all children as `untouched` |
| * and recalculates the `touched` status of all parent controls. |
| * |
| * @see `markAsTouched()` / `markAsDirty()` / `markAsPristine()` |
| * |
| * @param {?=} opts Configuration options that determine how the control propagates changes |
| * and emits events after the marking is applied. |
| * * `onlySelf`: When true, mark only this control. When false or not supplied, |
| * marks all direct ancestors. Default is false. |
| * @return {?} |
| */ |
| markAsUntouched(opts = {}) { |
| ((/** @type {?} */ (this))).touched = false; |
| this._pendingTouched = false; |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { control.markAsUntouched({ onlySelf: true }); })); |
| if (this._parent && !opts.onlySelf) { |
| this._parent._updateTouched(opts); |
| } |
| } |
| /** |
| * Marks the control as `dirty`. A control becomes dirty when |
| * the control's value is changed through the UI; compare `markAsTouched`. |
| * |
| * @see `markAsTouched()` / `markAsUntouched()` / `markAsPristine()` |
| * |
| * @param {?=} opts Configuration options that determine how the control propagates changes |
| * and emits events after marking is applied. |
| * * `onlySelf`: When true, mark only this control. When false or not supplied, |
| * marks all direct ancestors. Default is false. |
| * @return {?} |
| */ |
| markAsDirty(opts = {}) { |
| ((/** @type {?} */ (this))).pristine = false; |
| if (this._parent && !opts.onlySelf) { |
| this._parent.markAsDirty(opts); |
| } |
| } |
| /** |
| * Marks the control as `pristine`. |
| * |
| * If the control has any children, marks all children as `pristine`, |
| * and recalculates the `pristine` status of all parent |
| * controls. |
| * |
| * @see `markAsTouched()` / `markAsUntouched()` / `markAsDirty()` |
| * |
| * @param {?=} opts Configuration options that determine how the control emits events after |
| * marking is applied. |
| * * `onlySelf`: When true, mark only this control. When false or not supplied, |
| * marks all direct ancestors. Default is false.. |
| * @return {?} |
| */ |
| markAsPristine(opts = {}) { |
| ((/** @type {?} */ (this))).pristine = true; |
| this._pendingDirty = false; |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { control.markAsPristine({ onlySelf: true }); })); |
| if (this._parent && !opts.onlySelf) { |
| this._parent._updatePristine(opts); |
| } |
| } |
| /** |
| * Marks the control as `pending`. |
| * |
| * A control is pending while the control performs async validation. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @param {?=} opts Configuration options that determine how the control propagates changes and |
| * emits events after marking is applied. |
| * * `onlySelf`: When true, mark only this control. When false or not supplied, |
| * marks all direct ancestors. Default is false.. |
| * * `emitEvent`: When true or not supplied (the default), the `statusChanges` |
| * observable emits an event with the latest status the control is marked pending. |
| * When false, no events are emitted. |
| * |
| * @return {?} |
| */ |
| markAsPending(opts = {}) { |
| ((/** @type {?} */ (this))).status = PENDING; |
| if (opts.emitEvent !== false) { |
| ((/** @type {?} */ (this.statusChanges))).emit(this.status); |
| } |
| if (this._parent && !opts.onlySelf) { |
| this._parent.markAsPending(opts); |
| } |
| } |
| /** |
| * Disables the control. This means the control is exempt from validation checks and |
| * excluded from the aggregate value of any parent. Its status is `DISABLED`. |
| * |
| * If the control has children, all children are also disabled. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @param {?=} opts Configuration options that determine how the control propagates |
| * changes and emits events after the control is disabled. |
| * * `onlySelf`: When true, mark only this control. When false or not supplied, |
| * marks all direct ancestors. Default is false.. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control is disabled. |
| * When false, no events are emitted. |
| * @return {?} |
| */ |
| disable(opts = {}) { |
| // If parent has been marked artificially dirty we don't want to re-calculate the |
| // parent's dirtiness based on the children. |
| /** @type {?} */ |
| const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf); |
| ((/** @type {?} */ (this))).status = DISABLED; |
| ((/** @type {?} */ (this))).errors = null; |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { control.disable(Object.assign({}, opts, { onlySelf: true })); })); |
| this._updateValue(); |
| if (opts.emitEvent !== false) { |
| ((/** @type {?} */ (this.valueChanges))).emit(this.value); |
| ((/** @type {?} */ (this.statusChanges))).emit(this.status); |
| } |
| this._updateAncestors(Object.assign({}, opts, { skipPristineCheck })); |
| this._onDisabledChange.forEach((/** |
| * @param {?} changeFn |
| * @return {?} |
| */ |
| (changeFn) => changeFn(true))); |
| } |
| /** |
| * Enables the control. This means the control is included in validation checks and |
| * the aggregate value of its parent. Its status recalculates based on its value and |
| * its validators. |
| * |
| * By default, if the control has children, all children are enabled. |
| * |
| * @see {\@link AbstractControl.status} |
| * |
| * @param {?=} opts Configure options that control how the control propagates changes and |
| * emits events when marked as untouched |
| * * `onlySelf`: When true, mark only this control. When false or not supplied, |
| * marks all direct ancestors. Default is false.. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control is enabled. |
| * When false, no events are emitted. |
| * @return {?} |
| */ |
| enable(opts = {}) { |
| // If parent has been marked artificially dirty we don't want to re-calculate the |
| // parent's dirtiness based on the children. |
| /** @type {?} */ |
| const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf); |
| ((/** @type {?} */ (this))).status = VALID; |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { control.enable(Object.assign({}, opts, { onlySelf: true })); })); |
| this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent }); |
| this._updateAncestors(Object.assign({}, opts, { skipPristineCheck })); |
| this._onDisabledChange.forEach((/** |
| * @param {?} changeFn |
| * @return {?} |
| */ |
| (changeFn) => changeFn(false))); |
| } |
| /** |
| * @private |
| * @param {?} opts |
| * @return {?} |
| */ |
| _updateAncestors(opts) { |
| if (this._parent && !opts.onlySelf) { |
| this._parent.updateValueAndValidity(opts); |
| if (!opts.skipPristineCheck) { |
| this._parent._updatePristine(); |
| } |
| this._parent._updateTouched(); |
| } |
| } |
| /** |
| * @param {?} parent Sets the parent of the control |
| * @return {?} |
| */ |
| setParent(parent) { this._parent = parent; } |
| /** |
| * Recalculates the value and validation status of the control. |
| * |
| * By default, it also updates the value and validity of its ancestors. |
| * |
| * @param {?=} opts Configuration options determine how the control propagates changes and emits events |
| * after updates and validity checks are applied. |
| * * `onlySelf`: When true, only update this control. When false or not supplied, |
| * update all direct ancestors. Default is false.. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control is updated. |
| * When false, no events are emitted. |
| * @return {?} |
| */ |
| updateValueAndValidity(opts = {}) { |
| this._setInitialStatus(); |
| this._updateValue(); |
| if (this.enabled) { |
| this._cancelExistingSubscription(); |
| ((/** @type {?} */ (this))).errors = this._runValidator(); |
| ((/** @type {?} */ (this))).status = this._calculateStatus(); |
| if (this.status === VALID || this.status === PENDING) { |
| this._runAsyncValidator(opts.emitEvent); |
| } |
| } |
| if (opts.emitEvent !== false) { |
| ((/** @type {?} */ (this.valueChanges))).emit(this.value); |
| ((/** @type {?} */ (this.statusChanges))).emit(this.status); |
| } |
| if (this._parent && !opts.onlySelf) { |
| this._parent.updateValueAndValidity(opts); |
| } |
| } |
| /** |
| * \@internal |
| * @param {?=} opts |
| * @return {?} |
| */ |
| _updateTreeValidity(opts = { emitEvent: true }) { |
| this._forEachChild((/** |
| * @param {?} ctrl |
| * @return {?} |
| */ |
| (ctrl) => ctrl._updateTreeValidity(opts))); |
| this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent }); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _setInitialStatus() { |
| ((/** @type {?} */ (this))).status = this._allControlsDisabled() ? DISABLED : VALID; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _runValidator() { |
| return this.validator ? this.validator(this) : null; |
| } |
| /** |
| * @private |
| * @param {?=} emitEvent |
| * @return {?} |
| */ |
| _runAsyncValidator(emitEvent) { |
| if (this.asyncValidator) { |
| ((/** @type {?} */ (this))).status = PENDING; |
| /** @type {?} */ |
| const obs = toObservable(this.asyncValidator(this)); |
| this._asyncValidationSubscription = |
| obs.subscribe((/** |
| * @param {?} errors |
| * @return {?} |
| */ |
| (errors) => this.setErrors(errors, { emitEvent }))); |
| } |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _cancelExistingSubscription() { |
| if (this._asyncValidationSubscription) { |
| this._asyncValidationSubscription.unsubscribe(); |
| } |
| } |
| /** |
| * Sets errors on a form control when running validations manually, rather than automatically. |
| * |
| * Calling `setErrors` also updates the validity of the parent control. |
| * |
| * \@usageNotes |
| * ### Manually set the errors for a control |
| * |
| * ``` |
| * const login = new FormControl('someLogin'); |
| * login.setErrors({ |
| * notUnique: true |
| * }); |
| * |
| * expect(login.valid).toEqual(false); |
| * expect(login.errors).toEqual({ notUnique: true }); |
| * |
| * login.setValue('someOtherLogin'); |
| * |
| * expect(login.valid).toEqual(true); |
| * ``` |
| * @param {?} errors |
| * @param {?=} opts |
| * @return {?} |
| */ |
| setErrors(errors, opts = {}) { |
| ((/** @type {?} */ (this))).errors = errors; |
| this._updateControlsErrors(opts.emitEvent !== false); |
| } |
| /** |
| * Retrieves a child control given the control's name or path. |
| * |
| * \@usageNotes |
| * ### Retrieve a nested control |
| * |
| * For example, to get a `name` control nested within a `person` sub-group: |
| * |
| * * `this.form.get('person.name');` |
| * |
| * -OR- |
| * |
| * * `this.form.get(['person', 'name']);` |
| * @param {?} path A dot-delimited string or array of string/number values that define the path to the |
| * control. |
| * |
| * @return {?} |
| */ |
| get(path) { return _find(this, path, '.'); } |
| /** |
| * \@description |
| * Reports error data for the control with the given path. |
| * |
| * \@usageNotes |
| * For example, for the following `FormGroup`: |
| * |
| * ``` |
| * form = new FormGroup({ |
| * address: new FormGroup({ street: new FormControl() }) |
| * }); |
| * ``` |
| * |
| * The path to the 'street' control from the root form would be 'address' -> 'street'. |
| * |
| * It can be provided to this method in one of two formats: |
| * |
| * 1. An array of string control names, e.g. `['address', 'street']` |
| * 1. A period-delimited list of control names in one string, e.g. `'address.street'` |
| * |
| * @param {?} errorCode The code of the error to check |
| * @param {?=} path A list of control names that designates how to move from the current control |
| * to the control that should be queried for errors. |
| * |
| * @return {?} error data for that particular error. If the control or error is not present, |
| * null is returned. |
| */ |
| getError(errorCode, path) { |
| /** @type {?} */ |
| const control = path ? this.get(path) : this; |
| return control && control.errors ? control.errors[errorCode] : null; |
| } |
| /** |
| * \@description |
| * Reports whether the control with the given path has the error specified. |
| * |
| * \@usageNotes |
| * For example, for the following `FormGroup`: |
| * |
| * ``` |
| * form = new FormGroup({ |
| * address: new FormGroup({ street: new FormControl() }) |
| * }); |
| * ``` |
| * |
| * The path to the 'street' control from the root form would be 'address' -> 'street'. |
| * |
| * It can be provided to this method in one of two formats: |
| * |
| * 1. An array of string control names, e.g. `['address', 'street']` |
| * 1. A period-delimited list of control names in one string, e.g. `'address.street'` |
| * |
| * If no path is given, this method checks for the error on the current control. |
| * |
| * @param {?} errorCode The code of the error to check |
| * @param {?=} path A list of control names that designates how to move from the current control |
| * to the control that should be queried for errors. |
| * |
| * @return {?} whether the given error is present in the control at the given path. |
| * |
| * If the control is not present, false is returned. |
| */ |
| hasError(errorCode, path) { |
| return !!this.getError(errorCode, path); |
| } |
| /** |
| * Retrieves the top-level ancestor of this control. |
| * @return {?} |
| */ |
| get root() { |
| /** @type {?} */ |
| let x = this; |
| while (x._parent) { |
| x = x._parent; |
| } |
| return x; |
| } |
| /** |
| * \@internal |
| * @param {?} emitEvent |
| * @return {?} |
| */ |
| _updateControlsErrors(emitEvent) { |
| ((/** @type {?} */ (this))).status = this._calculateStatus(); |
| if (emitEvent) { |
| ((/** @type {?} */ (this.statusChanges))).emit(this.status); |
| } |
| if (this._parent) { |
| this._parent._updateControlsErrors(emitEvent); |
| } |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _initObservables() { |
| ((/** @type {?} */ (this))).valueChanges = new EventEmitter(); |
| ((/** @type {?} */ (this))).statusChanges = new EventEmitter(); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _calculateStatus() { |
| if (this._allControlsDisabled()) |
| return DISABLED; |
| if (this.errors) |
| return INVALID; |
| if (this._anyControlsHaveStatus(PENDING)) |
| return PENDING; |
| if (this._anyControlsHaveStatus(INVALID)) |
| return INVALID; |
| return VALID; |
| } |
| /** |
| * \@internal |
| * @param {?} status |
| * @return {?} |
| */ |
| _anyControlsHaveStatus(status) { |
| return this._anyControls((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control.status === status)); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _anyControlsDirty() { |
| return this._anyControls((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control.dirty)); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _anyControlsTouched() { |
| return this._anyControls((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control.touched)); |
| } |
| /** |
| * \@internal |
| * @param {?=} opts |
| * @return {?} |
| */ |
| _updatePristine(opts = {}) { |
| ((/** @type {?} */ (this))).pristine = !this._anyControlsDirty(); |
| if (this._parent && !opts.onlySelf) { |
| this._parent._updatePristine(opts); |
| } |
| } |
| /** |
| * \@internal |
| * @param {?=} opts |
| * @return {?} |
| */ |
| _updateTouched(opts = {}) { |
| ((/** @type {?} */ (this))).touched = this._anyControlsTouched(); |
| if (this._parent && !opts.onlySelf) { |
| this._parent._updateTouched(opts); |
| } |
| } |
| /** |
| * \@internal |
| * @param {?} formState |
| * @return {?} |
| */ |
| _isBoxedValue(formState) { |
| return typeof formState === 'object' && formState !== null && |
| Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState; |
| } |
| /** |
| * \@internal |
| * @param {?} fn |
| * @return {?} |
| */ |
| _registerOnCollectionChange(fn) { this._onCollectionChange = fn; } |
| /** |
| * \@internal |
| * @param {?=} opts |
| * @return {?} |
| */ |
| _setUpdateStrategy(opts) { |
| if (isOptionsObj(opts) && ((/** @type {?} */ (opts))).updateOn != null) { |
| this._updateOn = (/** @type {?} */ (((/** @type {?} */ (opts))).updateOn)); |
| } |
| } |
| /** |
| * Check to see if parent has been marked artificially dirty. |
| * |
| * \@internal |
| * @private |
| * @param {?=} onlySelf |
| * @return {?} |
| */ |
| _parentMarkedDirty(onlySelf) { |
| /** @type {?} */ |
| const parentDirty = this._parent && this._parent.dirty; |
| return !onlySelf && parentDirty && !this._parent._anyControlsDirty(); |
| } |
| } |
| /** |
| * Tracks the value and validation status of an individual form control. |
| * |
| * This is one of the three fundamental building blocks of Angular forms, along with |
| * `FormGroup` and `FormArray`. It extends the `AbstractControl` class that |
| * implements most of the base functionality for accessing the value, validation status, |
| * user interactions and events. |
| * |
| * @see `AbstractControl` |
| * @see [Reactive Forms Guide](guide/reactive-forms) |
| * @see [Usage Notes](#usage-notes) |
| * |
| * \@usageNotes |
| * |
| * ### Initializing Form Controls |
| * |
| * Instantiate a `FormControl`, with an initial value. |
| * |
| * ```ts |
| * const control = new FormControl('some value'); |
| * console.log(control.value); // 'some value' |
| * ``` |
| * |
| * The following example initializes the control with a form state object. The `value` |
| * and `disabled` keys are required in this case. |
| * |
| * ```ts |
| * const control = new FormControl({ value: 'n/a', disabled: true }); |
| * console.log(control.value); // 'n/a' |
| * console.log(control.status); // 'DISABLED' |
| * ``` |
| * |
| * The following example initializes the control with a sync validator. |
| * |
| * ```ts |
| * const control = new FormControl('', Validators.required); |
| * console.log(control.value); // '' |
| * console.log(control.status); // 'INVALID' |
| * ``` |
| * |
| * The following example initializes the control using an options object. |
| * |
| * ```ts |
| * const control = new FormControl('', { |
| * validators: Validators.required, |
| * asyncValidators: myAsyncValidator |
| * }); |
| * ``` |
| * |
| * ### Configure the control to update on a blur event |
| * |
| * Set the `updateOn` option to `'blur'` to update on the blur `event`. |
| * |
| * ```ts |
| * const control = new FormControl('', { updateOn: 'blur' }); |
| * ``` |
| * |
| * ### Configure the control to update on a submit event |
| * |
| * Set the `updateOn` option to `'submit'` to update on a submit `event`. |
| * |
| * ```ts |
| * const control = new FormControl('', { updateOn: 'submit' }); |
| * ``` |
| * |
| * ### Reset the control back to an initial value |
| * |
| * You reset to a specific form state by passing through a standalone |
| * value or a form state object that contains both a value and a disabled state |
| * (these are the only two properties that cannot be calculated). |
| * |
| * ```ts |
| * const control = new FormControl('Nancy'); |
| * |
| * console.log(control.value); // 'Nancy' |
| * |
| * control.reset('Drew'); |
| * |
| * console.log(control.value); // 'Drew' |
| * ``` |
| * |
| * ### Reset the control back to an initial value and disabled |
| * |
| * ``` |
| * const control = new FormControl('Nancy'); |
| * |
| * console.log(control.value); // 'Nancy' |
| * console.log(control.status); // 'VALID' |
| * |
| * control.reset({ value: 'Drew', disabled: true }); |
| * |
| * console.log(control.value); // 'Drew' |
| * console.log(control.status); // 'DISABLED' |
| * ``` |
| * |
| * \@publicApi |
| */ |
| class FormControl extends AbstractControl { |
| /** |
| * Creates a new `FormControl` instance. |
| * |
| * @param {?=} formState Initializes the control with an initial value, |
| * or an object that defines the initial value and disabled state. |
| * |
| * @param {?=} validatorOrOpts A synchronous validator function, or an array of |
| * such functions, or an `AbstractControlOptions` object that contains validation functions |
| * and a validation trigger. |
| * |
| * @param {?=} asyncValidator A single async validator or array of async validator functions |
| * |
| */ |
| constructor(formState = null, validatorOrOpts, asyncValidator) { |
| super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts)); |
| /** |
| * \@internal |
| */ |
| this._onChange = []; |
| this._applyFormState(formState); |
| this._setUpdateStrategy(validatorOrOpts); |
| this.updateValueAndValidity({ onlySelf: true, emitEvent: false }); |
| this._initObservables(); |
| } |
| /** |
| * Sets a new value for the form control. |
| * |
| * @param {?} value The new value for the control. |
| * @param {?=} options Configuration options that determine how the control propagates changes |
| * and emits events when the value changes. |
| * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity |
| * updateValueAndValidity} method. |
| * |
| * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is |
| * false. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control value is updated. |
| * When false, no events are emitted. |
| * * `emitModelToViewChange`: When true or not supplied (the default), each change triggers an |
| * `onChange` event to |
| * update the view. |
| * * `emitViewToModelChange`: When true or not supplied (the default), each change triggers an |
| * `ngModelChange` |
| * event to update the model. |
| * |
| * @return {?} |
| */ |
| setValue(value, options = {}) { |
| ((/** @type {?} */ (this))).value = this._pendingValue = value; |
| if (this._onChange.length && options.emitModelToViewChange !== false) { |
| this._onChange.forEach((/** |
| * @param {?} changeFn |
| * @return {?} |
| */ |
| (changeFn) => changeFn(this.value, options.emitViewToModelChange !== false))); |
| } |
| this.updateValueAndValidity(options); |
| } |
| /** |
| * Patches the value of a control. |
| * |
| * This function is functionally the same as {\@link FormControl#setValue setValue} at this level. |
| * It exists for symmetry with {\@link FormGroup#patchValue patchValue} on `FormGroups` and |
| * `FormArrays`, where it does behave differently. |
| * |
| * @see `setValue` for options |
| * @param {?} value |
| * @param {?=} options |
| * @return {?} |
| */ |
| patchValue(value, options = {}) { |
| this.setValue(value, options); |
| } |
| /** |
| * Resets the form control, marking it `pristine` and `untouched`, and setting |
| * the value to null. |
| * |
| * @param {?=} formState Resets the control with an initial value, |
| * or an object that defines the initial value and disabled state. |
| * |
| * @param {?=} options Configuration options that determine how the control propagates changes |
| * and emits events after the value changes. |
| * |
| * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is |
| * false. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control is reset. |
| * When false, no events are emitted. |
| * |
| * @return {?} |
| */ |
| reset(formState = null, options = {}) { |
| this._applyFormState(formState); |
| this.markAsPristine(options); |
| this.markAsUntouched(options); |
| this.setValue(this.value, options); |
| this._pendingChange = false; |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _updateValue() { } |
| /** |
| * \@internal |
| * @param {?} condition |
| * @return {?} |
| */ |
| _anyControls(condition) { return false; } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _allControlsDisabled() { return this.disabled; } |
| /** |
| * Register a listener for change events. |
| * |
| * @param {?} fn The method that is called when the value changes |
| * @return {?} |
| */ |
| registerOnChange(fn) { this._onChange.push(fn); } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _clearChangeFns() { |
| this._onChange = []; |
| this._onDisabledChange = []; |
| this._onCollectionChange = (/** |
| * @return {?} |
| */ |
| () => { }); |
| } |
| /** |
| * Register a listener for disabled events. |
| * |
| * @param {?} fn The method that is called when the disabled status changes. |
| * @return {?} |
| */ |
| registerOnDisabledChange(fn) { |
| this._onDisabledChange.push(fn); |
| } |
| /** |
| * \@internal |
| * @param {?} cb |
| * @return {?} |
| */ |
| _forEachChild(cb) { } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _syncPendingControls() { |
| if (this.updateOn === 'submit') { |
| if (this._pendingDirty) |
| this.markAsDirty(); |
| if (this._pendingTouched) |
| this.markAsTouched(); |
| if (this._pendingChange) { |
| this.setValue(this._pendingValue, { onlySelf: true, emitModelToViewChange: false }); |
| return true; |
| } |
| } |
| return false; |
| } |
| /** |
| * @private |
| * @param {?} formState |
| * @return {?} |
| */ |
| _applyFormState(formState) { |
| if (this._isBoxedValue(formState)) { |
| ((/** @type {?} */ (this))).value = this._pendingValue = formState.value; |
| formState.disabled ? this.disable({ onlySelf: true, emitEvent: false }) : |
| this.enable({ onlySelf: true, emitEvent: false }); |
| } |
| else { |
| ((/** @type {?} */ (this))).value = this._pendingValue = formState; |
| } |
| } |
| } |
| /** |
| * Tracks the value and validity state of a group of `FormControl` instances. |
| * |
| * A `FormGroup` aggregates the values of each child `FormControl` into one object, |
| * with each control name as the key. It calculates its status by reducing the status values |
| * of its children. For example, if one of the controls in a group is invalid, the entire |
| * group becomes invalid. |
| * |
| * `FormGroup` is one of the three fundamental building blocks used to define forms in Angular, |
| * along with `FormControl` and `FormArray`. |
| * |
| * When instantiating a `FormGroup`, pass in a collection of child controls as the first |
| * argument. The key for each child registers the name for the control. |
| * |
| * \@usageNotes |
| * |
| * ### Create a form group with 2 controls |
| * |
| * ``` |
| * const form = new FormGroup({ |
| * first: new FormControl('Nancy', Validators.minLength(2)), |
| * last: new FormControl('Drew'), |
| * }); |
| * |
| * console.log(form.value); // {first: 'Nancy', last; 'Drew'} |
| * console.log(form.status); // 'VALID' |
| * ``` |
| * |
| * ### Create a form group with a group-level validator |
| * |
| * You include group-level validators as the second arg, or group-level async |
| * validators as the third arg. These come in handy when you want to perform validation |
| * that considers the value of more than one child control. |
| * |
| * ``` |
| * const form = new FormGroup({ |
| * password: new FormControl('', Validators.minLength(2)), |
| * passwordConfirm: new FormControl('', Validators.minLength(2)), |
| * }, passwordMatchValidator); |
| * |
| * |
| * function passwordMatchValidator(g: FormGroup) { |
| * return g.get('password').value === g.get('passwordConfirm').value |
| * ? null : {'mismatch': true}; |
| * } |
| * ``` |
| * |
| * Like `FormControl` instances, you choose to pass in |
| * validators and async validators as part of an options object. |
| * |
| * ``` |
| * const form = new FormGroup({ |
| * password: new FormControl('') |
| * passwordConfirm: new FormControl('') |
| * }, { validators: passwordMatchValidator, asyncValidators: otherValidator }); |
| * ``` |
| * |
| * ### Set the updateOn property for all controls in a form group |
| * |
| * The options object is used to set a default value for each child |
| * control's `updateOn` property. If you set `updateOn` to `'blur'` at the |
| * group level, all child controls default to 'blur', unless the child |
| * has explicitly specified a different `updateOn` value. |
| * |
| * ```ts |
| * const c = new FormGroup({ |
| * one: new FormControl() |
| * }, { updateOn: 'blur' }); |
| * ``` |
| * |
| * \@publicApi |
| */ |
| class FormGroup extends AbstractControl { |
| /** |
| * Creates a new `FormGroup` instance. |
| * |
| * @param {?} controls A collection of child controls. The key for each child is the name |
| * under which it is registered. |
| * |
| * @param {?=} validatorOrOpts A synchronous validator function, or an array of |
| * such functions, or an `AbstractControlOptions` object that contains validation functions |
| * and a validation trigger. |
| * |
| * @param {?=} asyncValidator A single async validator or array of async validator functions |
| * |
| */ |
| constructor(controls, validatorOrOpts, asyncValidator) { |
| super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts)); |
| this.controls = controls; |
| this._initObservables(); |
| this._setUpdateStrategy(validatorOrOpts); |
| this._setUpControls(); |
| this.updateValueAndValidity({ onlySelf: true, emitEvent: false }); |
| } |
| /** |
| * Registers a control with the group's list of controls. |
| * |
| * This method does not update the value or validity of the control. |
| * Use {\@link FormGroup#addControl addControl} instead. |
| * |
| * @param {?} name The control name to register in the collection |
| * @param {?} control Provides the control for the given name |
| * @return {?} |
| */ |
| registerControl(name, control) { |
| if (this.controls[name]) |
| return this.controls[name]; |
| this.controls[name] = control; |
| control.setParent(this); |
| control._registerOnCollectionChange(this._onCollectionChange); |
| return control; |
| } |
| /** |
| * Add a control to this group. |
| * |
| * This method also updates the value and validity of the control. |
| * |
| * @param {?} name The control name to add to the collection |
| * @param {?} control Provides the control for the given name |
| * @return {?} |
| */ |
| addControl(name, control) { |
| this.registerControl(name, control); |
| this.updateValueAndValidity(); |
| this._onCollectionChange(); |
| } |
| /** |
| * Remove a control from this group. |
| * |
| * @param {?} name The control name to remove from the collection |
| * @return {?} |
| */ |
| removeControl(name) { |
| if (this.controls[name]) |
| this.controls[name]._registerOnCollectionChange((/** |
| * @return {?} |
| */ |
| () => { })); |
| delete (this.controls[name]); |
| this.updateValueAndValidity(); |
| this._onCollectionChange(); |
| } |
| /** |
| * Replace an existing control. |
| * |
| * @param {?} name The control name to replace in the collection |
| * @param {?} control Provides the control for the given name |
| * @return {?} |
| */ |
| setControl(name, control) { |
| if (this.controls[name]) |
| this.controls[name]._registerOnCollectionChange((/** |
| * @return {?} |
| */ |
| () => { })); |
| delete (this.controls[name]); |
| if (control) |
| this.registerControl(name, control); |
| this.updateValueAndValidity(); |
| this._onCollectionChange(); |
| } |
| /** |
| * Check whether there is an enabled control with the given name in the group. |
| * |
| * Reports false for disabled controls. If you'd like to check for existence in the group |
| * only, use {\@link AbstractControl#get get} instead. |
| * |
| * @param {?} controlName |
| * @return {?} false for disabled controls, true otherwise. |
| */ |
| contains(controlName) { |
| return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled; |
| } |
| /** |
| * Sets the value of the `FormGroup`. It accepts an object that matches |
| * the structure of the group, with control names as keys. |
| * |
| * \@usageNotes |
| * ### Set the complete value for the form group |
| * |
| * ``` |
| * const form = new FormGroup({ |
| * first: new FormControl(), |
| * last: new FormControl() |
| * }); |
| * |
| * console.log(form.value); // {first: null, last: null} |
| * |
| * form.setValue({first: 'Nancy', last: 'Drew'}); |
| * console.log(form.value); // {first: 'Nancy', last: 'Drew'} |
| * ``` |
| * |
| * @throws When strict checks fail, such as setting the value of a control |
| * that doesn't exist or if you excluding the value of a control. |
| * |
| * @param {?} value The new value for the control that matches the structure of the group. |
| * @param {?=} options Configuration options that determine how the control propagates changes |
| * and emits events after the value changes. |
| * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity |
| * updateValueAndValidity} method. |
| * |
| * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is |
| * false. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control value is updated. |
| * When false, no events are emitted. |
| * @return {?} |
| */ |
| setValue(value, options = {}) { |
| this._checkAllValuesPresent(value); |
| Object.keys(value).forEach((/** |
| * @param {?} name |
| * @return {?} |
| */ |
| name => { |
| this._throwIfControlMissing(name); |
| this.controls[name].setValue(value[name], { onlySelf: true, emitEvent: options.emitEvent }); |
| })); |
| this.updateValueAndValidity(options); |
| } |
| /** |
| * Patches the value of the `FormGroup`. It accepts an object with control |
| * names as keys, and does its best to match the values to the correct controls |
| * in the group. |
| * |
| * It accepts both super-sets and sub-sets of the group without throwing an error. |
| * |
| * \@usageNotes |
| * ### Patch the value for a form group |
| * |
| * ``` |
| * const form = new FormGroup({ |
| * first: new FormControl(), |
| * last: new FormControl() |
| * }); |
| * console.log(form.value); // {first: null, last: null} |
| * |
| * form.patchValue({first: 'Nancy'}); |
| * console.log(form.value); // {first: 'Nancy', last: null} |
| * ``` |
| * |
| * @param {?} value The object that matches the structure of the group. |
| * @param {?=} options Configuration options that determine how the control propagates changes and |
| * emits events after the value is patched. |
| * * `onlySelf`: When true, each change only affects this control and not its parent. Default is |
| * true. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control value is updated. |
| * When false, no events are emitted. |
| * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity |
| * updateValueAndValidity} method. |
| * @return {?} |
| */ |
| patchValue(value, options = {}) { |
| Object.keys(value).forEach((/** |
| * @param {?} name |
| * @return {?} |
| */ |
| name => { |
| if (this.controls[name]) { |
| this.controls[name].patchValue(value[name], { onlySelf: true, emitEvent: options.emitEvent }); |
| } |
| })); |
| this.updateValueAndValidity(options); |
| } |
| /** |
| * Resets the `FormGroup`, marks all descendants are marked `pristine` and `untouched`, and |
| * the value of all descendants to null. |
| * |
| * You reset to a specific form state by passing in a map of states |
| * that matches the structure of your form, with control names as keys. The state |
| * is a standalone value or a form state object with both a value and a disabled |
| * status. |
| * |
| * \@usageNotes |
| * |
| * ### Reset the form group values |
| * |
| * ```ts |
| * const form = new FormGroup({ |
| * first: new FormControl('first name'), |
| * last: new FormControl('last name') |
| * }); |
| * |
| * console.log(form.value); // {first: 'first name', last: 'last name'} |
| * |
| * form.reset({ first: 'name', last: 'last name' }); |
| * |
| * console.log(form.value); // {first: 'name', last: 'last name'} |
| * ``` |
| * |
| * ### Reset the form group values and disabled status |
| * |
| * ``` |
| * const form = new FormGroup({ |
| * first: new FormControl('first name'), |
| * last: new FormControl('last name') |
| * }); |
| * |
| * form.reset({ |
| * first: {value: 'name', disabled: true}, |
| * last: 'last' |
| * }); |
| * |
| * console.log(this.form.value); // {first: 'name', last: 'last name'} |
| * console.log(this.form.get('first').status); // 'DISABLED' |
| * ``` |
| * @param {?=} value |
| * @param {?=} options Configuration options that determine how the control propagates changes |
| * and emits events when the group is reset. |
| * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is |
| * false. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control is reset. |
| * When false, no events are emitted. |
| * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity |
| * updateValueAndValidity} method. |
| * |
| * @return {?} |
| */ |
| reset(value = {}, options = {}) { |
| this._forEachChild((/** |
| * @param {?} control |
| * @param {?} name |
| * @return {?} |
| */ |
| (control, name) => { |
| control.reset(value[name], { onlySelf: true, emitEvent: options.emitEvent }); |
| })); |
| this._updatePristine(options); |
| this._updateTouched(options); |
| this.updateValueAndValidity(options); |
| } |
| /** |
| * The aggregate value of the `FormGroup`, including any disabled controls. |
| * |
| * Retrieves all values regardless of disabled status. |
| * The `value` property is the best way to get the value of the group, because |
| * it excludes disabled controls in the `FormGroup`. |
| * @return {?} |
| */ |
| getRawValue() { |
| return this._reduceChildren({}, (/** |
| * @param {?} acc |
| * @param {?} control |
| * @param {?} name |
| * @return {?} |
| */ |
| (acc, control, name) => { |
| acc[name] = control instanceof FormControl ? control.value : ((/** @type {?} */ (control))).getRawValue(); |
| return acc; |
| })); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _syncPendingControls() { |
| /** @type {?} */ |
| let subtreeUpdated = this._reduceChildren(false, (/** |
| * @param {?} updated |
| * @param {?} child |
| * @return {?} |
| */ |
| (updated, child) => { |
| return child._syncPendingControls() ? true : updated; |
| })); |
| if (subtreeUpdated) |
| this.updateValueAndValidity({ onlySelf: true }); |
| return subtreeUpdated; |
| } |
| /** |
| * \@internal |
| * @param {?} name |
| * @return {?} |
| */ |
| _throwIfControlMissing(name) { |
| if (!Object.keys(this.controls).length) { |
| throw new Error(` |
| There are no form controls registered with this group yet. If you're using ngModel, |
| you may want to check next tick (e.g. use setTimeout). |
| `); |
| } |
| if (!this.controls[name]) { |
| throw new Error(`Cannot find form control with name: ${name}.`); |
| } |
| } |
| /** |
| * \@internal |
| * @param {?} cb |
| * @return {?} |
| */ |
| _forEachChild(cb) { |
| Object.keys(this.controls).forEach((/** |
| * @param {?} k |
| * @return {?} |
| */ |
| k => cb(this.controls[k], k))); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _setUpControls() { |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { |
| control.setParent(this); |
| control._registerOnCollectionChange(this._onCollectionChange); |
| })); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _updateValue() { ((/** @type {?} */ (this))).value = this._reduceValue(); } |
| /** |
| * \@internal |
| * @param {?} condition |
| * @return {?} |
| */ |
| _anyControls(condition) { |
| /** @type {?} */ |
| let res = false; |
| this._forEachChild((/** |
| * @param {?} control |
| * @param {?} name |
| * @return {?} |
| */ |
| (control, name) => { |
| res = res || (this.contains(name) && condition(control)); |
| })); |
| return res; |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _reduceValue() { |
| return this._reduceChildren({}, (/** |
| * @param {?} acc |
| * @param {?} control |
| * @param {?} name |
| * @return {?} |
| */ |
| (acc, control, name) => { |
| if (control.enabled || this.disabled) { |
| acc[name] = control.value; |
| } |
| return acc; |
| })); |
| } |
| /** |
| * \@internal |
| * @param {?} initValue |
| * @param {?} fn |
| * @return {?} |
| */ |
| _reduceChildren(initValue, fn) { |
| /** @type {?} */ |
| let res = initValue; |
| this._forEachChild((/** |
| * @param {?} control |
| * @param {?} name |
| * @return {?} |
| */ |
| (control, name) => { res = fn(res, control, name); })); |
| return res; |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _allControlsDisabled() { |
| for (const controlName of Object.keys(this.controls)) { |
| if (this.controls[controlName].enabled) { |
| return false; |
| } |
| } |
| return Object.keys(this.controls).length > 0 || this.disabled; |
| } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _checkAllValuesPresent(value) { |
| this._forEachChild((/** |
| * @param {?} control |
| * @param {?} name |
| * @return {?} |
| */ |
| (control, name) => { |
| if (value[name] === undefined) { |
| throw new Error(`Must supply a value for form control with name: '${name}'.`); |
| } |
| })); |
| } |
| } |
| /** |
| * Tracks the value and validity state of an array of `FormControl`, |
| * `FormGroup` or `FormArray` instances. |
| * |
| * A `FormArray` aggregates the values of each child `FormControl` into an array. |
| * It calculates its status by reducing the status values of its children. For example, if one of |
| * the controls in a `FormArray` is invalid, the entire array becomes invalid. |
| * |
| * `FormArray` is one of the three fundamental building blocks used to define forms in Angular, |
| * along with `FormControl` and `FormGroup`. |
| * |
| * \@usageNotes |
| * |
| * ### Create an array of form controls |
| * |
| * ``` |
| * const arr = new FormArray([ |
| * new FormControl('Nancy', Validators.minLength(2)), |
| * new FormControl('Drew'), |
| * ]); |
| * |
| * console.log(arr.value); // ['Nancy', 'Drew'] |
| * console.log(arr.status); // 'VALID' |
| * ``` |
| * |
| * ### Create a form array with array-level validators |
| * |
| * You include array-level validators and async validators. These come in handy |
| * when you want to perform validation that considers the value of more than one child |
| * control. |
| * |
| * The two types of validators are passed in separately as the second and third arg |
| * respectively, or together as part of an options object. |
| * |
| * ``` |
| * const arr = new FormArray([ |
| * new FormControl('Nancy'), |
| * new FormControl('Drew') |
| * ], {validators: myValidator, asyncValidators: myAsyncValidator}); |
| * ``` |
| * |
| * ### Set the updateOn property for all controls in a form array |
| * |
| * The options object is used to set a default value for each child |
| * control's `updateOn` property. If you set `updateOn` to `'blur'` at the |
| * array level, all child controls default to 'blur', unless the child |
| * has explicitly specified a different `updateOn` value. |
| * |
| * ```ts |
| * const arr = new FormArray([ |
| * new FormControl() |
| * ], {updateOn: 'blur'}); |
| * ``` |
| * |
| * ### Adding or removing controls from a form array |
| * |
| * To change the controls in the array, use the `push`, `insert`, `removeAt` or `clear` methods |
| * in `FormArray` itself. These methods ensure the controls are properly tracked in the |
| * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate |
| * the `FormArray` directly, as that result in strange and unexpected behavior such |
| * as broken change detection. |
| * |
| * \@publicApi |
| */ |
| class FormArray extends AbstractControl { |
| /** |
| * Creates a new `FormArray` instance. |
| * |
| * @param {?} controls An array of child controls. Each child control is given an index |
| * where it is registered. |
| * |
| * @param {?=} validatorOrOpts A synchronous validator function, or an array of |
| * such functions, or an `AbstractControlOptions` object that contains validation functions |
| * and a validation trigger. |
| * |
| * @param {?=} asyncValidator A single async validator or array of async validator functions |
| * |
| */ |
| constructor(controls, validatorOrOpts, asyncValidator) { |
| super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts)); |
| this.controls = controls; |
| this._initObservables(); |
| this._setUpdateStrategy(validatorOrOpts); |
| this._setUpControls(); |
| this.updateValueAndValidity({ onlySelf: true, emitEvent: false }); |
| } |
| /** |
| * Get the `AbstractControl` at the given `index` in the array. |
| * |
| * @param {?} index Index in the array to retrieve the control |
| * @return {?} |
| */ |
| at(index) { return this.controls[index]; } |
| /** |
| * Insert a new `AbstractControl` at the end of the array. |
| * |
| * @param {?} control Form control to be inserted |
| * @return {?} |
| */ |
| push(control) { |
| this.controls.push(control); |
| this._registerControl(control); |
| this.updateValueAndValidity(); |
| this._onCollectionChange(); |
| } |
| /** |
| * Insert a new `AbstractControl` at the given `index` in the array. |
| * |
| * @param {?} index Index in the array to insert the control |
| * @param {?} control Form control to be inserted |
| * @return {?} |
| */ |
| insert(index, control) { |
| this.controls.splice(index, 0, control); |
| this._registerControl(control); |
| this.updateValueAndValidity(); |
| } |
| /** |
| * Remove the control at the given `index` in the array. |
| * |
| * @param {?} index Index in the array to remove the control |
| * @return {?} |
| */ |
| removeAt(index) { |
| if (this.controls[index]) |
| this.controls[index]._registerOnCollectionChange((/** |
| * @return {?} |
| */ |
| () => { })); |
| this.controls.splice(index, 1); |
| this.updateValueAndValidity(); |
| } |
| /** |
| * Replace an existing control. |
| * |
| * @param {?} index Index in the array to replace the control |
| * @param {?} control The `AbstractControl` control to replace the existing control |
| * @return {?} |
| */ |
| setControl(index, control) { |
| if (this.controls[index]) |
| this.controls[index]._registerOnCollectionChange((/** |
| * @return {?} |
| */ |
| () => { })); |
| this.controls.splice(index, 1); |
| if (control) { |
| this.controls.splice(index, 0, control); |
| this._registerControl(control); |
| } |
| this.updateValueAndValidity(); |
| this._onCollectionChange(); |
| } |
| /** |
| * Length of the control array. |
| * @return {?} |
| */ |
| get length() { return this.controls.length; } |
| /** |
| * Sets the value of the `FormArray`. It accepts an array that matches |
| * the structure of the control. |
| * |
| * This method performs strict checks, and throws an error if you try |
| * to set the value of a control that doesn't exist or if you exclude the |
| * value of a control. |
| * |
| * \@usageNotes |
| * ### Set the values for the controls in the form array |
| * |
| * ``` |
| * const arr = new FormArray([ |
| * new FormControl(), |
| * new FormControl() |
| * ]); |
| * console.log(arr.value); // [null, null] |
| * |
| * arr.setValue(['Nancy', 'Drew']); |
| * console.log(arr.value); // ['Nancy', 'Drew'] |
| * ``` |
| * |
| * @param {?} value Array of values for the controls |
| * @param {?=} options Configure options that determine how the control propagates changes and |
| * emits events after the value changes |
| * |
| * * `onlySelf`: When true, each change only affects this control, and not its parent. Default |
| * is false. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control value is updated. |
| * When false, no events are emitted. |
| * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity |
| * updateValueAndValidity} method. |
| * @return {?} |
| */ |
| setValue(value, options = {}) { |
| this._checkAllValuesPresent(value); |
| value.forEach((/** |
| * @param {?} newValue |
| * @param {?} index |
| * @return {?} |
| */ |
| (newValue, index) => { |
| this._throwIfControlMissing(index); |
| this.at(index).setValue(newValue, { onlySelf: true, emitEvent: options.emitEvent }); |
| })); |
| this.updateValueAndValidity(options); |
| } |
| /** |
| * Patches the value of the `FormArray`. It accepts an array that matches the |
| * structure of the control, and does its best to match the values to the correct |
| * controls in the group. |
| * |
| * It accepts both super-sets and sub-sets of the array without throwing an error. |
| * |
| * \@usageNotes |
| * ### Patch the values for controls in a form array |
| * |
| * ``` |
| * const arr = new FormArray([ |
| * new FormControl(), |
| * new FormControl() |
| * ]); |
| * console.log(arr.value); // [null, null] |
| * |
| * arr.patchValue(['Nancy']); |
| * console.log(arr.value); // ['Nancy', null] |
| * ``` |
| * |
| * @param {?} value Array of latest values for the controls |
| * @param {?=} options Configure options that determine how the control propagates changes and |
| * emits events after the value changes |
| * |
| * * `onlySelf`: When true, each change only affects this control, and not its parent. Default |
| * is false. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control value is updated. |
| * When false, no events are emitted. |
| * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity |
| * updateValueAndValidity} method. |
| * @return {?} |
| */ |
| patchValue(value, options = {}) { |
| value.forEach((/** |
| * @param {?} newValue |
| * @param {?} index |
| * @return {?} |
| */ |
| (newValue, index) => { |
| if (this.at(index)) { |
| this.at(index).patchValue(newValue, { onlySelf: true, emitEvent: options.emitEvent }); |
| } |
| })); |
| this.updateValueAndValidity(options); |
| } |
| /** |
| * Resets the `FormArray` and all descendants are marked `pristine` and `untouched`, and the |
| * value of all descendants to null or null maps. |
| * |
| * You reset to a specific form state by passing in an array of states |
| * that matches the structure of the control. The state is a standalone value |
| * or a form state object with both a value and a disabled status. |
| * |
| * \@usageNotes |
| * ### Reset the values in a form array |
| * |
| * ```ts |
| * const arr = new FormArray([ |
| * new FormControl(), |
| * new FormControl() |
| * ]); |
| * arr.reset(['name', 'last name']); |
| * |
| * console.log(this.arr.value); // ['name', 'last name'] |
| * ``` |
| * |
| * ### Reset the values in a form array and the disabled status for the first control |
| * |
| * ``` |
| * this.arr.reset([ |
| * {value: 'name', disabled: true}, |
| * 'last' |
| * ]); |
| * |
| * console.log(this.arr.value); // ['name', 'last name'] |
| * console.log(this.arr.get(0).status); // 'DISABLED' |
| * ``` |
| * |
| * @param {?=} value Array of values for the controls |
| * @param {?=} options Configure options that determine how the control propagates changes and |
| * emits events after the value changes |
| * |
| * * `onlySelf`: When true, each change only affects this control, and not its parent. Default |
| * is false. |
| * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and |
| * `valueChanges` |
| * observables emit events with the latest status and value when the control is reset. |
| * When false, no events are emitted. |
| * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity |
| * updateValueAndValidity} method. |
| * @return {?} |
| */ |
| reset(value = [], options = {}) { |
| this._forEachChild((/** |
| * @param {?} control |
| * @param {?} index |
| * @return {?} |
| */ |
| (control, index) => { |
| control.reset(value[index], { onlySelf: true, emitEvent: options.emitEvent }); |
| })); |
| this._updatePristine(options); |
| this._updateTouched(options); |
| this.updateValueAndValidity(options); |
| } |
| /** |
| * The aggregate value of the array, including any disabled controls. |
| * |
| * Reports all values regardless of disabled status. |
| * For enabled controls only, the `value` property is the best way to get the value of the array. |
| * @return {?} |
| */ |
| getRawValue() { |
| return this.controls.map((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => { |
| return control instanceof FormControl ? control.value : ((/** @type {?} */ (control))).getRawValue(); |
| })); |
| } |
| /** |
| * Remove all controls in the `FormArray`. |
| * |
| * \@usageNotes |
| * ### Remove all elements from a FormArray |
| * |
| * ```ts |
| * const arr = new FormArray([ |
| * new FormControl(), |
| * new FormControl() |
| * ]); |
| * console.log(arr.length); // 2 |
| * |
| * arr.clear(); |
| * console.log(arr.length); // 0 |
| * ``` |
| * |
| * It's a simpler and more efficient alternative to removing all elements one by one: |
| * |
| * ```ts |
| * const arr = new FormArray([ |
| * new FormControl(), |
| * new FormControl() |
| * ]); |
| * |
| * while (arr.length) { |
| * arr.removeAt(0); |
| * } |
| * ``` |
| * @return {?} |
| */ |
| clear() { |
| if (this.controls.length < 1) |
| return; |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control._registerOnCollectionChange((/** |
| * @return {?} |
| */ |
| () => { })))); |
| this.controls.splice(0); |
| this.updateValueAndValidity(); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _syncPendingControls() { |
| /** @type {?} */ |
| let subtreeUpdated = this.controls.reduce((/** |
| * @param {?} updated |
| * @param {?} child |
| * @return {?} |
| */ |
| (updated, child) => { |
| return child._syncPendingControls() ? true : updated; |
| }), false); |
| if (subtreeUpdated) |
| this.updateValueAndValidity({ onlySelf: true }); |
| return subtreeUpdated; |
| } |
| /** |
| * \@internal |
| * @param {?} index |
| * @return {?} |
| */ |
| _throwIfControlMissing(index) { |
| if (!this.controls.length) { |
| throw new Error(` |
| There are no form controls registered with this array yet. If you're using ngModel, |
| you may want to check next tick (e.g. use setTimeout). |
| `); |
| } |
| if (!this.at(index)) { |
| throw new Error(`Cannot find form control at index ${index}`); |
| } |
| } |
| /** |
| * \@internal |
| * @param {?} cb |
| * @return {?} |
| */ |
| _forEachChild(cb) { |
| this.controls.forEach((/** |
| * @param {?} control |
| * @param {?} index |
| * @return {?} |
| */ |
| (control, index) => { cb(control, index); })); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _updateValue() { |
| ((/** @type {?} */ (this))).value = |
| this.controls.filter((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control.enabled || this.disabled)) |
| .map((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control.value)); |
| } |
| /** |
| * \@internal |
| * @param {?} condition |
| * @return {?} |
| */ |
| _anyControls(condition) { |
| return this.controls.some((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => control.enabled && condition(control))); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _setUpControls() { |
| this._forEachChild((/** |
| * @param {?} control |
| * @return {?} |
| */ |
| (control) => this._registerControl(control))); |
| } |
| /** |
| * \@internal |
| * @param {?} value |
| * @return {?} |
| */ |
| _checkAllValuesPresent(value) { |
| this._forEachChild((/** |
| * @param {?} control |
| * @param {?} i |
| * @return {?} |
| */ |
| (control, i) => { |
| if (value[i] === undefined) { |
| throw new Error(`Must supply a value for form control at index: ${i}.`); |
| } |
| })); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _allControlsDisabled() { |
| for (const control of this.controls) { |
| if (control.enabled) |
| return false; |
| } |
| return this.controls.length > 0 || this.disabled; |
| } |
| /** |
| * @private |
| * @param {?} control |
| * @return {?} |
| */ |
| _registerControl(control) { |
| control.setParent(this); |
| control._registerOnCollectionChange(this._onCollectionChange); |
| } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const formDirectiveProvider = { |
| provide: ControlContainer, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => NgForm)) |
| }; |
| const ɵ0 = /** |
| * @return {?} |
| */ |
| () => Promise.resolve(null); |
| /** @type {?} */ |
| const resolvedPromise = ((ɵ0))(); |
| /** |
| * \@description |
| * Creates a top-level `FormGroup` instance and binds it to a form |
| * to track aggregate form value and validation status. |
| * |
| * As soon as you import the `FormsModule`, this directive becomes active by default on |
| * all `<form>` tags. You don't need to add a special selector. |
| * |
| * You optionally export the directive into a local template variable using `ngForm` as the key |
| * (ex: `#myForm="ngForm"`). This is optional, but useful. Many properties from the underlying |
| * `FormGroup` instance are duplicated on the directive itself, so a reference to it |
| * gives you access to the aggregate value and validity status of the form, as well as |
| * user interaction properties like `dirty` and `touched`. |
| * |
| * To register child controls with the form, use `NgModel` with a `name` |
| * attribute. You may use `NgModelGroup` to create sub-groups within the form. |
| * |
| * If necessary, listen to the directive's `ngSubmit` event to be notified when the user has |
| * triggered a form submission. The `ngSubmit` event emits the original form |
| * submission event. |
| * |
| * In template driven forms, all `<form>` tags are automatically tagged as `NgForm`. |
| * To import the `FormsModule` but skip its usage in some forms, |
| * for example, to use native HTML5 validation, add the `ngNoForm` and the `<form>` |
| * tags won't create an `NgForm` directive. In reactive forms, using `ngNoForm` is |
| * unnecessary because the `<form>` tags are inert. In that case, you would |
| * refrain from using the `formGroup` directive. |
| * |
| * \@usageNotes |
| * |
| * ### Migrating from deprecated ngForm selector |
| * |
| * Support for using `ngForm` element selector has been deprecated in Angular v6 and will be removed |
| * in Angular v9. |
| * |
| * This has been deprecated to keep selectors consistent with other core Angular selectors, |
| * as element selectors are typically written in kebab-case. |
| * |
| * Now deprecated: |
| * ```html |
| * <ngForm #myForm="ngForm"> |
| * ``` |
| * |
| * After: |
| * ```html |
| * <ng-form #myForm="ngForm"> |
| * ``` |
| * |
| * ### Listening for form submission |
| * |
| * The following example shows how to capture the form values from the "ngSubmit" event. |
| * |
| * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'} |
| * |
| * ### Setting the update options |
| * |
| * The following example shows you how to change the "updateOn" option from its default using |
| * ngFormOptions. |
| * |
| * ```html |
| * <form [ngFormOptions]="{updateOn: 'blur'}"> |
| * <input name="one" ngModel> <!-- this ngModel will update on blur --> |
| * </form> |
| * ``` |
| * |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NgForm extends ControlContainer { |
| /** |
| * @param {?} validators |
| * @param {?} asyncValidators |
| */ |
| constructor(validators, asyncValidators) { |
| super(); |
| /** |
| * \@description |
| * Returns whether the form submission has been triggered. |
| */ |
| this.submitted = false; |
| this._directives = []; |
| /** |
| * \@description |
| * Event emitter for the "ngSubmit" event |
| */ |
| this.ngSubmit = new EventEmitter(); |
| this.form = |
| new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators)); |
| } |
| /** |
| * \@description |
| * Lifecycle method called after the view is initialized. For internal use only. |
| * @return {?} |
| */ |
| ngAfterViewInit() { this._setUpdateStrategy(); } |
| /** |
| * \@description |
| * The directive instance. |
| * @return {?} |
| */ |
| get formDirective() { return this; } |
| /** |
| * \@description |
| * The internal `FormGroup` instance. |
| * @return {?} |
| */ |
| get control() { return this.form; } |
| /** |
| * \@description |
| * Returns an array representing the path to this group. Because this directive |
| * always lives at the top level of a form, it is always an empty array. |
| * @return {?} |
| */ |
| get path() { return []; } |
| /** |
| * \@description |
| * Returns a map of the controls in this group. |
| * @return {?} |
| */ |
| get controls() { return this.form.controls; } |
| /** |
| * \@description |
| * Method that sets up the control directive in this group, re-calculates its value |
| * and validity, and adds the instance to the internal list of directives. |
| * |
| * @param {?} dir The `NgModel` directive instance. |
| * @return {?} |
| */ |
| addControl(dir) { |
| resolvedPromise.then((/** |
| * @return {?} |
| */ |
| () => { |
| /** @type {?} */ |
| const container = this._findContainer(dir.path); |
| ((/** @type {?} */ (dir))).control = |
| (/** @type {?} */ (container.registerControl(dir.name, dir.control))); |
| setUpControl(dir.control, dir); |
| dir.control.updateValueAndValidity({ emitEvent: false }); |
| this._directives.push(dir); |
| })); |
| } |
| /** |
| * \@description |
| * Retrieves the `FormControl` instance from the provided `NgModel` directive. |
| * |
| * @param {?} dir The `NgModel` directive instance. |
| * @return {?} |
| */ |
| getControl(dir) { return (/** @type {?} */ (this.form.get(dir.path))); } |
| /** |
| * \@description |
| * Removes the `NgModel` instance from the internal list of directives |
| * |
| * @param {?} dir The `NgModel` directive instance. |
| * @return {?} |
| */ |
| removeControl(dir) { |
| resolvedPromise.then((/** |
| * @return {?} |
| */ |
| () => { |
| /** @type {?} */ |
| const container = this._findContainer(dir.path); |
| if (container) { |
| container.removeControl(dir.name); |
| } |
| removeDir(this._directives, dir); |
| })); |
| } |
| /** |
| * \@description |
| * Adds a new `NgModelGroup` directive instance to the form. |
| * |
| * @param {?} dir The `NgModelGroup` directive instance. |
| * @return {?} |
| */ |
| addFormGroup(dir) { |
| resolvedPromise.then((/** |
| * @return {?} |
| */ |
| () => { |
| /** @type {?} */ |
| const container = this._findContainer(dir.path); |
| /** @type {?} */ |
| const group = new FormGroup({}); |
| setUpFormContainer(group, dir); |
| container.registerControl(dir.name, group); |
| group.updateValueAndValidity({ emitEvent: false }); |
| })); |
| } |
| /** |
| * \@description |
| * Removes the `NgModelGroup` directive instance from the form. |
| * |
| * @param {?} dir The `NgModelGroup` directive instance. |
| * @return {?} |
| */ |
| removeFormGroup(dir) { |
| resolvedPromise.then((/** |
| * @return {?} |
| */ |
| () => { |
| /** @type {?} */ |
| const container = this._findContainer(dir.path); |
| if (container) { |
| container.removeControl(dir.name); |
| } |
| })); |
| } |
| /** |
| * \@description |
| * Retrieves the `FormGroup` for a provided `NgModelGroup` directive instance |
| * |
| * @param {?} dir The `NgModelGroup` directive instance. |
| * @return {?} |
| */ |
| getFormGroup(dir) { return (/** @type {?} */ (this.form.get(dir.path))); } |
| /** |
| * Sets the new value for the provided `NgControl` directive. |
| * |
| * @param {?} dir The `NgControl` directive instance. |
| * @param {?} value The new value for the directive's control. |
| * @return {?} |
| */ |
| updateModel(dir, value) { |
| resolvedPromise.then((/** |
| * @return {?} |
| */ |
| () => { |
| /** @type {?} */ |
| const ctrl = (/** @type {?} */ (this.form.get((/** @type {?} */ (dir.path))))); |
| ctrl.setValue(value); |
| })); |
| } |
| /** |
| * \@description |
| * Sets the value for this `FormGroup`. |
| * |
| * @param {?} value The new value |
| * @return {?} |
| */ |
| setValue(value) { this.control.setValue(value); } |
| /** |
| * \@description |
| * Method called when the "submit" event is triggered on the form. |
| * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload. |
| * |
| * @param {?} $event The "submit" event object |
| * @return {?} |
| */ |
| onSubmit($event) { |
| ((/** @type {?} */ (this))).submitted = true; |
| syncPendingControls(this.form, this._directives); |
| this.ngSubmit.emit($event); |
| return false; |
| } |
| /** |
| * \@description |
| * Method called when the "reset" event is triggered on the form. |
| * @return {?} |
| */ |
| onReset() { this.resetForm(); } |
| /** |
| * \@description |
| * Resets the form to an initial value and resets its submitted status. |
| * |
| * @param {?=} value The new value for the form. |
| * @return {?} |
| */ |
| resetForm(value = undefined) { |
| this.form.reset(value); |
| ((/** @type {?} */ (this))).submitted = false; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _setUpdateStrategy() { |
| if (this.options && this.options.updateOn != null) { |
| this.form._updateOn = this.options.updateOn; |
| } |
| } |
| /** |
| * \@internal |
| * @param {?} path |
| * @return {?} |
| */ |
| _findContainer(path) { |
| path.pop(); |
| return path.length ? (/** @type {?} */ (this.form.get(path))) : this.form; |
| } |
| } |
| NgForm.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,ng-form,[ngForm]', |
| providers: [formDirectiveProvider], |
| host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' }, |
| outputs: ['ngSubmit'], |
| exportAs: 'ngForm' |
| },] } |
| ]; |
| /** @nocollapse */ |
| NgForm.ctorParameters = () => [ |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] } |
| ]; |
| NgForm.propDecorators = { |
| options: [{ type: Input, args: ['ngFormOptions',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| class TemplateDrivenErrors { |
| /** |
| * @return {?} |
| */ |
| static modelParentException() { |
| throw new Error(` |
| ngModel cannot be used to register form controls with a parent formGroup directive. Try using |
| formGroup's partner directive "formControlName" instead. Example: |
| |
| ${FormErrorExamples.formControlName} |
| |
| Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions: |
| |
| Example: |
| |
| ${FormErrorExamples.ngModelWithFormGroup}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static formGroupNameException() { |
| throw new Error(` |
| ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive. |
| |
| Option 1: Use formControlName instead of ngModel (reactive strategy): |
| |
| ${FormErrorExamples.formGroupName} |
| |
| Option 2: Update ngModel's parent be ngModelGroup (template-driven strategy): |
| |
| ${FormErrorExamples.ngModelGroup}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static missingNameException() { |
| throw new Error(`If ngModel is used within a form tag, either the name attribute must be set or the form |
| control must be defined as 'standalone' in ngModelOptions. |
| |
| Example 1: <input [(ngModel)]="person.firstName" name="first"> |
| Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">`); |
| } |
| /** |
| * @return {?} |
| */ |
| static modelGroupParentException() { |
| throw new Error(` |
| ngModelGroup cannot be used with a parent formGroup directive. |
| |
| Option 1: Use formGroupName instead of ngModelGroup (reactive strategy): |
| |
| ${FormErrorExamples.formGroupName} |
| |
| Option 2: Use a regular form tag instead of the formGroup directive (template-driven strategy): |
| |
| ${FormErrorExamples.ngModelGroup}`); |
| } |
| /** |
| * @return {?} |
| */ |
| static ngFormWarning() { |
| console.warn(` |
| It looks like you're using 'ngForm'. |
| |
| Support for using the 'ngForm' element selector has been deprecated in Angular v6 and will be removed |
| in Angular v9. |
| |
| Use 'ng-form' instead. |
| |
| Before: |
| <ngForm #myForm="ngForm"> |
| |
| After: |
| <ng-form #myForm="ngForm"> |
| `); |
| } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * \@description |
| * `InjectionToken` to provide to turn off the warning when using 'ngForm' deprecated selector. |
| * @type {?} |
| */ |
| const NG_FORM_SELECTOR_WARNING = new InjectionToken('NgFormSelectorWarning'); |
| /** |
| * This directive is solely used to display warnings when the deprecated `ngForm` selector is used. |
| * |
| * @deprecated in Angular v6 and will be removed in Angular v9. |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NgFormSelectorWarning { |
| /** |
| * @param {?} ngFormWarning |
| */ |
| constructor(ngFormWarning) { |
| if (((!ngFormWarning || ngFormWarning === 'once') && !NgFormSelectorWarning._ngFormWarning) || |
| ngFormWarning === 'always') { |
| TemplateDrivenErrors.ngFormWarning(); |
| NgFormSelectorWarning._ngFormWarning = true; |
| } |
| } |
| } |
| /** |
| * Static property used to track whether the deprecation warning for this selector has been sent. |
| * Used to support warning config of "once". |
| * |
| * \@internal |
| */ |
| NgFormSelectorWarning._ngFormWarning = false; |
| NgFormSelectorWarning.decorators = [ |
| { type: Directive, args: [{ selector: 'ngForm' },] } |
| ]; |
| /** @nocollapse */ |
| NgFormSelectorWarning.ctorParameters = () => [ |
| { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NG_FORM_SELECTOR_WARNING,] }] } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * \@description |
| * A base class for code shared between the `NgModelGroup` and `FormGroupName` directives. |
| * |
| * \@publicApi |
| */ |
| class AbstractFormGroupDirective extends ControlContainer { |
| /** |
| * \@description |
| * An internal callback method triggered on the instance after the inputs are set. |
| * Registers the group with its parent group. |
| * @return {?} |
| */ |
| ngOnInit() { |
| this._checkParentType(); |
| (/** @type {?} */ (this.formDirective)).addFormGroup(this); |
| } |
| /** |
| * \@description |
| * An internal callback method triggered before the instance is destroyed. |
| * Removes the group from its parent group. |
| * @return {?} |
| */ |
| ngOnDestroy() { |
| if (this.formDirective) { |
| this.formDirective.removeFormGroup(this); |
| } |
| } |
| /** |
| * \@description |
| * The `FormGroup` bound to this directive. |
| * @return {?} |
| */ |
| get control() { return (/** @type {?} */ (this.formDirective)).getFormGroup(this); } |
| /** |
| * \@description |
| * The path to this group from the top-level directive. |
| * @return {?} |
| */ |
| get path() { return controlPath(this.name, this._parent); } |
| /** |
| * \@description |
| * The top-level directive for this group if present, otherwise null. |
| * @return {?} |
| */ |
| get formDirective() { return this._parent ? this._parent.formDirective : null; } |
| /** |
| * \@description |
| * The synchronous validators registered with this group. |
| * @return {?} |
| */ |
| get validator() { return composeValidators(this._validators); } |
| /** |
| * \@description |
| * The async validators registered with this group. |
| * @return {?} |
| */ |
| get asyncValidator() { |
| return composeAsyncValidators(this._asyncValidators); |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _checkParentType() { } |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const modelGroupProvider = { |
| provide: ControlContainer, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => NgModelGroup)) |
| }; |
| /** |
| * \@description |
| * Creates and binds a `FormGroup` instance to a DOM element. |
| * |
| * This directive can only be used as a child of `NgForm` (within `<form>` tags). |
| * |
| * Use this directive to validate a sub-group of your form separately from the |
| * rest of your form, or if some values in your domain model make more sense |
| * to consume together in a nested object. |
| * |
| * Provide a name for the sub-group and it will become the key |
| * for the sub-group in the form's full value. If you need direct access, export the directive into |
| * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`). |
| * |
| * \@usageNotes |
| * |
| * ### Consuming controls in a grouping |
| * |
| * The following example shows you how to combine controls together in a sub-group |
| * of the form. |
| * |
| * {\@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'} |
| * |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NgModelGroup extends AbstractFormGroupDirective { |
| /** |
| * @param {?} parent |
| * @param {?} validators |
| * @param {?} asyncValidators |
| */ |
| constructor(parent, validators, asyncValidators) { |
| super(); |
| this._parent = parent; |
| this._validators = validators; |
| this._asyncValidators = asyncValidators; |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _checkParentType() { |
| if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) { |
| TemplateDrivenErrors.modelGroupParentException(); |
| } |
| } |
| } |
| NgModelGroup.decorators = [ |
| { type: Directive, args: [{ selector: '[ngModelGroup]', providers: [modelGroupProvider], exportAs: 'ngModelGroup' },] } |
| ]; |
| /** @nocollapse */ |
| NgModelGroup.ctorParameters = () => [ |
| { type: ControlContainer, decorators: [{ type: Host }, { type: SkipSelf }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] } |
| ]; |
| NgModelGroup.propDecorators = { |
| name: [{ type: Input, args: ['ngModelGroup',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const formControlBinding = { |
| provide: NgControl, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => NgModel)) |
| }; |
| const ɵ0$1 = /** |
| * @return {?} |
| */ |
| () => Promise.resolve(null); |
| /** |
| * `ngModel` forces an additional change detection run when its inputs change: |
| * E.g.: |
| * ``` |
| * <div>{{myModel.valid}}</div> |
| * <input [(ngModel)]="myValue" #myModel="ngModel"> |
| * ``` |
| * I.e. `ngModel` can export itself on the element and then be used in the template. |
| * Normally, this would result in expressions before the `input` that use the exported directive |
| * to have and old value as they have been |
| * dirty checked before. As this is a very common case for `ngModel`, we added this second change |
| * detection run. |
| * |
| * Notes: |
| * - this is just one extra run no matter how many `ngModel` have been changed. |
| * - this is a general problem when using `exportAs` for directives! |
| * @type {?} |
| */ |
| const resolvedPromise$1 = ((ɵ0$1))(); |
| /** |
| * \@description |
| * Creates a `FormControl` instance from a domain model and binds it |
| * to a form control element. |
| * |
| * The `FormControl` instance tracks the value, user interaction, and |
| * validation status of the control and keeps the view synced with the model. If used |
| * within a parent form, the directive also registers itself with the form as a child |
| * control. |
| * |
| * This directive is used by itself or as part of a larger form. Use the |
| * `ngModel` selector to activate it. |
| * |
| * It accepts a domain model as an optional `Input`. If you have a one-way binding |
| * to `ngModel` with `[]` syntax, changing the value of the domain model in the component |
| * class sets the value in the view. If you have a two-way binding with `[()]` syntax |
| * (also known as 'banana-box syntax'), the value in the UI always syncs back to |
| * the domain model in your class. |
| * |
| * To inspect the properties of the associated `FormControl` (like validity state), |
| * export the directive into a local template variable using `ngModel` as the key (ex: `#myVar="ngModel"`). |
| * You then access the control using the directive's `control` property, |
| * but most properties used (like `valid` and `dirty`) fall through to the control anyway for direct access. |
| * See a full list of properties directly available in `AbstractControlDirective`. |
| * |
| * @see `RadioControlValueAccessor` |
| * @see `SelectControlValueAccessor` |
| * |
| * \@usageNotes |
| * |
| * ### Using ngModel on a standalone control |
| * |
| * The following examples show a simple standalone control using `ngModel`: |
| * |
| * {\@example forms/ts/simpleNgModel/simple_ng_model_example.ts region='Component'} |
| * |
| * When using the `ngModel` within `<form>` tags, you'll also need to supply a `name` attribute |
| * so that the control can be registered with the parent form under that name. |
| * |
| * In the context of a parent form, it's often unnecessary to include one-way or two-way binding, |
| * as the parent form syncs the value for you. You access its properties by exporting it into a |
| * local template variable using `ngForm` such as (`#f="ngForm"`). Use the variable where |
| * needed on form submission. |
| * |
| * If you do need to populate initial values into your form, using a one-way binding for |
| * `ngModel` tends to be sufficient as long as you use the exported form's value rather |
| * than the domain model's value on submit. |
| * |
| * ### Using ngModel within a form |
| * |
| * The following example shows controls using `ngModel` within a form: |
| * |
| * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'} |
| * |
| * ### Using a standalone ngModel within a group |
| * |
| * The following example shows you how to use a standalone ngModel control |
| * within a form. This controls the display of the form, but doesn't contain form data. |
| * |
| * ```html |
| * <form> |
| * <input name="login" ngModel placeholder="Login"> |
| * <input type="checkbox" ngModel [ngModelOptions]="{standalone: true}"> Show more options? |
| * </form> |
| * <!-- form value: {login: ''} --> |
| * ``` |
| * |
| * ### Setting the ngModel name attribute through options |
| * |
| * The following example shows you an alternate way to set the name attribute. The name attribute is used |
| * within a custom form component, and the name `\@Input` property serves a different purpose. |
| * |
| * ```html |
| * <form> |
| * <my-person-control name="Nancy" ngModel [ngModelOptions]="{name: 'user'}"> |
| * </my-person-control> |
| * </form> |
| * <!-- form value: {user: ''} --> |
| * ``` |
| * |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class NgModel extends NgControl { |
| /** |
| * @param {?} parent |
| * @param {?} validators |
| * @param {?} asyncValidators |
| * @param {?} valueAccessors |
| */ |
| constructor(parent, validators, asyncValidators, valueAccessors) { |
| super(); |
| this.control = new FormControl(); |
| /** |
| * \@internal |
| */ |
| this._registered = false; |
| /** |
| * \@description |
| * Event emitter for producing the `ngModelChange` event after |
| * the view model updates. |
| */ |
| this.update = new EventEmitter(); |
| this._parent = parent; |
| this._rawValidators = validators || []; |
| this._rawAsyncValidators = asyncValidators || []; |
| this.valueAccessor = selectValueAccessor(this, valueAccessors); |
| } |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs change. For internal use |
| * only. |
| * |
| * @param {?} changes A object of key/value pairs for the set of changed inputs. |
| * @return {?} |
| */ |
| ngOnChanges(changes) { |
| this._checkForErrors(); |
| if (!this._registered) |
| this._setUpControl(); |
| if ('isDisabled' in changes) { |
| this._updateDisabled(changes); |
| } |
| if (isPropertyUpdated(changes, this.viewModel)) { |
| this._updateValue(this.model); |
| this.viewModel = this.model; |
| } |
| } |
| /** |
| * \@description |
| * Lifecycle method called before the directive's instance is destroyed. For internal |
| * use only. |
| * @return {?} |
| */ |
| ngOnDestroy() { this.formDirective && this.formDirective.removeControl(this); } |
| /** |
| * \@description |
| * Returns an array that represents the path from the top-level form to this control. |
| * Each index is the string name of the control on that level. |
| * @return {?} |
| */ |
| get path() { |
| return this._parent ? controlPath(this.name, this._parent) : [this.name]; |
| } |
| /** |
| * \@description |
| * The top-level directive for this control if present, otherwise null. |
| * @return {?} |
| */ |
| get formDirective() { return this._parent ? this._parent.formDirective : null; } |
| /** |
| * \@description |
| * Synchronous validator function composed of all the synchronous validators |
| * registered with this directive. |
| * @return {?} |
| */ |
| get validator() { return composeValidators(this._rawValidators); } |
| /** |
| * \@description |
| * Async validator function composed of all the async validators registered with this |
| * directive. |
| * @return {?} |
| */ |
| get asyncValidator() { |
| return composeAsyncValidators(this._rawAsyncValidators); |
| } |
| /** |
| * \@description |
| * Sets the new value for the view model and emits an `ngModelChange` event. |
| * |
| * @param {?} newValue The new value emitted by `ngModelChange`. |
| * @return {?} |
| */ |
| viewToModelUpdate(newValue) { |
| this.viewModel = newValue; |
| this.update.emit(newValue); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _setUpControl() { |
| this._setUpdateStrategy(); |
| this._isStandalone() ? this._setUpStandalone() : |
| this.formDirective.addControl(this); |
| this._registered = true; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _setUpdateStrategy() { |
| if (this.options && this.options.updateOn != null) { |
| this.control._updateOn = this.options.updateOn; |
| } |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _isStandalone() { |
| return !this._parent || !!(this.options && this.options.standalone); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _setUpStandalone() { |
| setUpControl(this.control, this); |
| this.control.updateValueAndValidity({ emitEvent: false }); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _checkForErrors() { |
| if (!this._isStandalone()) { |
| this._checkParentType(); |
| } |
| this._checkName(); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _checkParentType() { |
| if (!(this._parent instanceof NgModelGroup) && |
| this._parent instanceof AbstractFormGroupDirective) { |
| TemplateDrivenErrors.formGroupNameException(); |
| } |
| else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) { |
| TemplateDrivenErrors.modelParentException(); |
| } |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _checkName() { |
| if (this.options && this.options.name) |
| this.name = this.options.name; |
| if (!this._isStandalone() && !this.name) { |
| TemplateDrivenErrors.missingNameException(); |
| } |
| } |
| /** |
| * @private |
| * @param {?} value |
| * @return {?} |
| */ |
| _updateValue(value) { |
| resolvedPromise$1.then((/** |
| * @return {?} |
| */ |
| () => { this.control.setValue(value, { emitViewToModelChange: false }); })); |
| } |
| /** |
| * @private |
| * @param {?} changes |
| * @return {?} |
| */ |
| _updateDisabled(changes) { |
| /** @type {?} */ |
| const disabledValue = changes['isDisabled'].currentValue; |
| /** @type {?} */ |
| const isDisabled = disabledValue === '' || (disabledValue && disabledValue !== 'false'); |
| resolvedPromise$1.then((/** |
| * @return {?} |
| */ |
| () => { |
| if (isDisabled && !this.control.disabled) { |
| this.control.disable(); |
| } |
| else if (!isDisabled && this.control.disabled) { |
| this.control.enable(); |
| } |
| })); |
| } |
| } |
| NgModel.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[ngModel]:not([formControlName]):not([formControl])', |
| providers: [formControlBinding], |
| exportAs: 'ngModel' |
| },] } |
| ]; |
| /** @nocollapse */ |
| NgModel.ctorParameters = () => [ |
| { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] }] } |
| ]; |
| NgModel.propDecorators = { |
| name: [{ type: Input }], |
| isDisabled: [{ type: Input, args: ['disabled',] }], |
| model: [{ type: Input, args: ['ngModel',] }], |
| options: [{ type: Input, args: ['ngModelOptions',] }], |
| update: [{ type: Output, args: ['ngModelChange',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * \@description |
| * |
| * Adds `novalidate` attribute to all forms by default. |
| * |
| * `novalidate` is used to disable browser's native form validation. |
| * |
| * If you want to use native validation with Angular forms, just add `ngNativeValidate` attribute: |
| * |
| * ``` |
| * <form ngNativeValidate></form> |
| * ``` |
| * |
| * \@publicApi |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| */ |
| class ɵNgNoValidate { |
| } |
| ɵNgNoValidate.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'form:not([ngNoForm]):not([ngNativeValidate])', |
| host: { 'novalidate': '' }, |
| },] } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * Token to provide to turn off the ngModel warning on formControl and formControlName. |
| * @type {?} |
| */ |
| const NG_MODEL_WITH_FORM_CONTROL_WARNING = new InjectionToken('NgModelWithFormControlWarning'); |
| /** @type {?} */ |
| const formControlBinding$1 = { |
| provide: NgControl, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => FormControlDirective)) |
| }; |
| /** |
| * \@description |
| * * Syncs a standalone `FormControl` instance to a form control element. |
| * |
| * @see [Reactive Forms Guide](guide/reactive-forms) |
| * @see `FormControl` |
| * @see `AbstractControl` |
| * |
| * \@usageNotes |
| * |
| * ### Registering a single form control |
| * |
| * The following examples shows how to register a standalone control and set its value. |
| * |
| * {\@example forms/ts/simpleFormControl/simple_form_control_example.ts region='Component'} |
| * |
| * ### Use with ngModel |
| * |
| * Support for using the `ngModel` input property and `ngModelChange` event with reactive |
| * form directives has been deprecated in Angular v6 and will be removed in Angular v7. |
| * |
| * Now deprecated: |
| * |
| * ```html |
| * <input [formControl]="control" [(ngModel)]="value"> |
| * ``` |
| * |
| * ```ts |
| * this.value = 'some value'; |
| * ``` |
| * |
| * This has been deprecated for a few reasons. First, developers have found this pattern |
| * confusing. It seems like the actual `ngModel` directive is being used, but in fact it's |
| * an input/output property named `ngModel` on the reactive form directive that simply |
| * approximates (some of) its behavior. Specifically, it allows getting/setting the value |
| * and intercepting value events. However, some of `ngModel`'s other features - like |
| * delaying updates with`ngModelOptions` or exporting the directive - simply don't work, |
| * which has understandably caused some confusion. |
| * |
| * In addition, this pattern mixes template-driven and reactive forms strategies, which |
| * we generally don't recommend because it doesn't take advantage of the full benefits of |
| * either strategy. Setting the value in the template violates the template-agnostic |
| * principles behind reactive forms, whereas adding a `FormControl`/`FormGroup` layer in |
| * the class removes the convenience of defining forms in the template. |
| * |
| * To update your code before v7, you'll want to decide whether to stick with reactive form |
| * directives (and get/set values using reactive forms patterns) or switch over to |
| * template-driven directives. |
| * |
| * After (choice 1 - use reactive forms): |
| * |
| * ```html |
| * <input [formControl]="control"> |
| * ``` |
| * |
| * ```ts |
| * this.control.setValue('some value'); |
| * ``` |
| * |
| * After (choice 2 - use template-driven forms): |
| * |
| * ```html |
| * <input [(ngModel)]="value"> |
| * ``` |
| * |
| * ```ts |
| * this.value = 'some value'; |
| * ``` |
| * |
| * By default, when you use this pattern, you will see a deprecation warning once in dev |
| * mode. You can choose to silence this warning by providing a config for |
| * `ReactiveFormsModule` at import time: |
| * |
| * ```ts |
| * imports: [ |
| * ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'}); |
| * ] |
| * ``` |
| * |
| * Alternatively, you can choose to surface a separate warning for each instance of this |
| * pattern with a config value of `"always"`. This may help to track down where in the code |
| * the pattern is being used as the code is being updated. |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@publicApi |
| */ |
| class FormControlDirective extends NgControl { |
| /** |
| * @param {?} validators |
| * @param {?} asyncValidators |
| * @param {?} valueAccessors |
| * @param {?} _ngModelWarningConfig |
| */ |
| constructor(validators, asyncValidators, valueAccessors, _ngModelWarningConfig) { |
| super(); |
| this._ngModelWarningConfig = _ngModelWarningConfig; |
| /** |
| * @deprecated as of v6 |
| */ |
| this.update = new EventEmitter(); |
| /** |
| * \@description |
| * Instance property used to track whether an ngModel warning has been sent out for this |
| * particular `FormControlDirective` instance. Used to support warning config of "always". |
| * |
| * \@internal |
| */ |
| this._ngModelWarningSent = false; |
| this._rawValidators = validators || []; |
| this._rawAsyncValidators = asyncValidators || []; |
| this.valueAccessor = selectValueAccessor(this, valueAccessors); |
| } |
| /** |
| * \@description |
| * Triggers a warning that this input should not be used with reactive forms. |
| * @param {?} isDisabled |
| * @return {?} |
| */ |
| set isDisabled(isDisabled) { ReactiveErrors.disabledAttrWarning(); } |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs change. For internal use |
| * only. |
| * |
| * @param {?} changes A object of key/value pairs for the set of changed inputs. |
| * @return {?} |
| */ |
| ngOnChanges(changes) { |
| if (this._isControlChanged(changes)) { |
| setUpControl(this.form, this); |
| if (this.control.disabled && (/** @type {?} */ (this.valueAccessor)).setDisabledState) { |
| (/** @type {?} */ ((/** @type {?} */ (this.valueAccessor)).setDisabledState))(true); |
| } |
| this.form.updateValueAndValidity({ emitEvent: false }); |
| } |
| if (isPropertyUpdated(changes, this.viewModel)) { |
| _ngModelWarning('formControl', FormControlDirective, this, this._ngModelWarningConfig); |
| this.form.setValue(this.model); |
| this.viewModel = this.model; |
| } |
| } |
| /** |
| * \@description |
| * Returns an array that represents the path from the top-level form to this control. |
| * Each index is the string name of the control on that level. |
| * @return {?} |
| */ |
| get path() { return []; } |
| /** |
| * \@description |
| * Synchronous validator function composed of all the synchronous validators |
| * registered with this directive. |
| * @return {?} |
| */ |
| get validator() { return composeValidators(this._rawValidators); } |
| /** |
| * \@description |
| * Async validator function composed of all the async validators registered with this |
| * directive. |
| * @return {?} |
| */ |
| get asyncValidator() { |
| return composeAsyncValidators(this._rawAsyncValidators); |
| } |
| /** |
| * \@description |
| * The `FormControl` bound to this directive. |
| * @return {?} |
| */ |
| get control() { return this.form; } |
| /** |
| * \@description |
| * Sets the new value for the view model and emits an `ngModelChange` event. |
| * |
| * @param {?} newValue The new value for the view model. |
| * @return {?} |
| */ |
| viewToModelUpdate(newValue) { |
| this.viewModel = newValue; |
| this.update.emit(newValue); |
| } |
| /** |
| * @private |
| * @param {?} changes |
| * @return {?} |
| */ |
| _isControlChanged(changes) { |
| return changes.hasOwnProperty('form'); |
| } |
| } |
| /** |
| * \@description |
| * Static property used to track whether any ngModel warnings have been sent across |
| * all instances of FormControlDirective. Used to support warning config of "once". |
| * |
| * \@internal |
| */ |
| FormControlDirective._ngModelWarningSentOnce = false; |
| FormControlDirective.decorators = [ |
| { type: Directive, args: [{ selector: '[formControl]', providers: [formControlBinding$1], exportAs: 'ngForm' },] } |
| ]; |
| /** @nocollapse */ |
| FormControlDirective.ctorParameters = () => [ |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] }] }, |
| { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NG_MODEL_WITH_FORM_CONTROL_WARNING,] }] } |
| ]; |
| FormControlDirective.propDecorators = { |
| form: [{ type: Input, args: ['formControl',] }], |
| isDisabled: [{ type: Input, args: ['disabled',] }], |
| model: [{ type: Input, args: ['ngModel',] }], |
| update: [{ type: Output, args: ['ngModelChange',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const formDirectiveProvider$1 = { |
| provide: ControlContainer, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => FormGroupDirective)) |
| }; |
| /** |
| * \@description |
| * |
| * Binds an existing `FormGroup` to a DOM element. |
| * |
| * This directive accepts an existing `FormGroup` instance. It will then use this |
| * `FormGroup` instance to match any child `FormControl`, `FormGroup`, |
| * and `FormArray` instances to child `FormControlName`, `FormGroupName`, |
| * and `FormArrayName` directives. |
| * |
| * @see [Reactive Forms Guide](guide/reactive-forms) |
| * @see `AbstractControl` |
| * |
| * ### Register Form Group |
| * |
| * The following example registers a `FormGroup` with first name and last name controls, |
| * and listens for the *ngSubmit* event when the button is clicked. |
| * |
| * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'} |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@publicApi |
| */ |
| class FormGroupDirective extends ControlContainer { |
| /** |
| * @param {?} _validators |
| * @param {?} _asyncValidators |
| */ |
| constructor(_validators, _asyncValidators) { |
| super(); |
| this._validators = _validators; |
| this._asyncValidators = _asyncValidators; |
| /** |
| * \@description |
| * Reports whether the form submission has been triggered. |
| */ |
| this.submitted = false; |
| /** |
| * \@description |
| * Tracks the list of added `FormControlName` instances |
| */ |
| this.directives = []; |
| /** |
| * \@description |
| * Tracks the `FormGroup` bound to this directive. |
| */ |
| this.form = (/** @type {?} */ (null)); |
| /** |
| * \@description |
| * Emits an event when the form submission has been triggered. |
| */ |
| this.ngSubmit = new EventEmitter(); |
| } |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs change. For internal use only. |
| * |
| * @param {?} changes A object of key/value pairs for the set of changed inputs. |
| * @return {?} |
| */ |
| ngOnChanges(changes) { |
| this._checkFormPresent(); |
| if (changes.hasOwnProperty('form')) { |
| this._updateValidators(); |
| this._updateDomValue(); |
| this._updateRegistrations(); |
| } |
| } |
| /** |
| * \@description |
| * Returns this directive's instance. |
| * @return {?} |
| */ |
| get formDirective() { return this; } |
| /** |
| * \@description |
| * Returns the `FormGroup` bound to this directive. |
| * @return {?} |
| */ |
| get control() { return this.form; } |
| /** |
| * \@description |
| * Returns an array representing the path to this group. Because this directive |
| * always lives at the top level of a form, it always an empty array. |
| * @return {?} |
| */ |
| get path() { return []; } |
| /** |
| * \@description |
| * Method that sets up the control directive in this group, re-calculates its value |
| * and validity, and adds the instance to the internal list of directives. |
| * |
| * @param {?} dir The `FormControlName` directive instance. |
| * @return {?} |
| */ |
| addControl(dir) { |
| /** @type {?} */ |
| const ctrl = this.form.get(dir.path); |
| setUpControl(ctrl, dir); |
| ctrl.updateValueAndValidity({ emitEvent: false }); |
| this.directives.push(dir); |
| return ctrl; |
| } |
| /** |
| * \@description |
| * Retrieves the `FormControl` instance from the provided `FormControlName` directive |
| * |
| * @param {?} dir The `FormControlName` directive instance. |
| * @return {?} |
| */ |
| getControl(dir) { return (/** @type {?} */ (this.form.get(dir.path))); } |
| /** |
| * \@description |
| * Removes the `FormControlName` instance from the internal list of directives |
| * |
| * @param {?} dir The `FormControlName` directive instance. |
| * @return {?} |
| */ |
| removeControl(dir) { removeDir(this.directives, dir); } |
| /** |
| * Adds a new `FormGroupName` directive instance to the form. |
| * |
| * @param {?} dir The `FormGroupName` directive instance. |
| * @return {?} |
| */ |
| addFormGroup(dir) { |
| /** @type {?} */ |
| const ctrl = this.form.get(dir.path); |
| setUpFormContainer(ctrl, dir); |
| ctrl.updateValueAndValidity({ emitEvent: false }); |
| } |
| /** |
| * No-op method to remove the form group. |
| * |
| * @param {?} dir The `FormGroupName` directive instance. |
| * @return {?} |
| */ |
| removeFormGroup(dir) { } |
| /** |
| * \@description |
| * Retrieves the `FormGroup` for a provided `FormGroupName` directive instance |
| * |
| * @param {?} dir The `FormGroupName` directive instance. |
| * @return {?} |
| */ |
| getFormGroup(dir) { return (/** @type {?} */ (this.form.get(dir.path))); } |
| /** |
| * Adds a new `FormArrayName` directive instance to the form. |
| * |
| * @param {?} dir The `FormArrayName` directive instance. |
| * @return {?} |
| */ |
| addFormArray(dir) { |
| /** @type {?} */ |
| const ctrl = this.form.get(dir.path); |
| setUpFormContainer(ctrl, dir); |
| ctrl.updateValueAndValidity({ emitEvent: false }); |
| } |
| /** |
| * No-op method to remove the form array. |
| * |
| * @param {?} dir The `FormArrayName` directive instance. |
| * @return {?} |
| */ |
| removeFormArray(dir) { } |
| /** |
| * \@description |
| * Retrieves the `FormArray` for a provided `FormArrayName` directive instance. |
| * |
| * @param {?} dir The `FormArrayName` directive instance. |
| * @return {?} |
| */ |
| getFormArray(dir) { return (/** @type {?} */ (this.form.get(dir.path))); } |
| /** |
| * Sets the new value for the provided `FormControlName` directive. |
| * |
| * @param {?} dir The `FormControlName` directive instance. |
| * @param {?} value The new value for the directive's control. |
| * @return {?} |
| */ |
| updateModel(dir, value) { |
| /** @type {?} */ |
| const ctrl = (/** @type {?} */ (this.form.get(dir.path))); |
| ctrl.setValue(value); |
| } |
| /** |
| * \@description |
| * Method called with the "submit" event is triggered on the form. |
| * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload. |
| * |
| * @param {?} $event The "submit" event object |
| * @return {?} |
| */ |
| onSubmit($event) { |
| ((/** @type {?} */ (this))).submitted = true; |
| syncPendingControls(this.form, this.directives); |
| this.ngSubmit.emit($event); |
| return false; |
| } |
| /** |
| * \@description |
| * Method called when the "reset" event is triggered on the form. |
| * @return {?} |
| */ |
| onReset() { this.resetForm(); } |
| /** |
| * \@description |
| * Resets the form to an initial value and resets its submitted status. |
| * |
| * @param {?=} value The new value for the form. |
| * @return {?} |
| */ |
| resetForm(value = undefined) { |
| this.form.reset(value); |
| ((/** @type {?} */ (this))).submitted = false; |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _updateDomValue() { |
| this.directives.forEach((/** |
| * @param {?} dir |
| * @return {?} |
| */ |
| dir => { |
| /** @type {?} */ |
| const newCtrl = this.form.get(dir.path); |
| if (dir.control !== newCtrl) { |
| cleanUpControl(dir.control, dir); |
| if (newCtrl) |
| setUpControl(newCtrl, dir); |
| ((/** @type {?} */ (dir))).control = newCtrl; |
| } |
| })); |
| this.form._updateTreeValidity({ emitEvent: false }); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _updateRegistrations() { |
| this.form._registerOnCollectionChange((/** |
| * @return {?} |
| */ |
| () => this._updateDomValue())); |
| if (this._oldForm) |
| this._oldForm._registerOnCollectionChange((/** |
| * @return {?} |
| */ |
| () => { })); |
| this._oldForm = this.form; |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _updateValidators() { |
| /** @type {?} */ |
| const sync = composeValidators(this._validators); |
| this.form.validator = Validators.compose([(/** @type {?} */ (this.form.validator)), (/** @type {?} */ (sync))]); |
| /** @type {?} */ |
| const async = composeAsyncValidators(this._asyncValidators); |
| this.form.asyncValidator = Validators.composeAsync([(/** @type {?} */ (this.form.asyncValidator)), (/** @type {?} */ (async))]); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _checkFormPresent() { |
| if (!this.form) { |
| ReactiveErrors.missingFormException(); |
| } |
| } |
| } |
| FormGroupDirective.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[formGroup]', |
| providers: [formDirectiveProvider$1], |
| host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' }, |
| exportAs: 'ngForm' |
| },] } |
| ]; |
| /** @nocollapse */ |
| FormGroupDirective.ctorParameters = () => [ |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] } |
| ]; |
| FormGroupDirective.propDecorators = { |
| form: [{ type: Input, args: ['formGroup',] }], |
| ngSubmit: [{ type: Output }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const formGroupNameProvider = { |
| provide: ControlContainer, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => FormGroupName)) |
| }; |
| /** |
| * \@description |
| * |
| * Syncs a nested `FormGroup` to a DOM element. |
| * |
| * This directive can only be used with a parent `FormGroupDirective`. |
| * |
| * It accepts the string name of the nested `FormGroup` to link, and |
| * looks for a `FormGroup` registered with that name in the parent |
| * `FormGroup` instance you passed into `FormGroupDirective`. |
| * |
| * Use nested form groups to validate a sub-group of a |
| * form separately from the rest or to group the values of certain |
| * controls into their own nested object. |
| * |
| * @see [Reactive Forms Guide](guide/reactive-forms) |
| * |
| * \@usageNotes |
| * |
| * ### Access the group by name |
| * |
| * The following example uses the {\@link AbstractControl#get get} method to access the |
| * associated `FormGroup` |
| * |
| * ```ts |
| * this.form.get('name'); |
| * ``` |
| * |
| * ### Access individual controls in the group |
| * |
| * The following example uses the {\@link AbstractControl#get get} method to access |
| * individual controls within the group using dot syntax. |
| * |
| * ```ts |
| * this.form.get('name.first'); |
| * ``` |
| * |
| * ### Register a nested `FormGroup`. |
| * |
| * The following example registers a nested *name* `FormGroup` within an existing `FormGroup`, |
| * and provides methods to retrieve the nested `FormGroup` and individual controls. |
| * |
| * {\@example forms/ts/nestedFormGroup/nested_form_group_example.ts region='Component'} |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@publicApi |
| */ |
| class FormGroupName extends AbstractFormGroupDirective { |
| /** |
| * @param {?} parent |
| * @param {?} validators |
| * @param {?} asyncValidators |
| */ |
| constructor(parent, validators, asyncValidators) { |
| super(); |
| this._parent = parent; |
| this._validators = validators; |
| this._asyncValidators = asyncValidators; |
| } |
| /** |
| * \@internal |
| * @return {?} |
| */ |
| _checkParentType() { |
| if (_hasInvalidParent(this._parent)) { |
| ReactiveErrors.groupParentException(); |
| } |
| } |
| } |
| FormGroupName.decorators = [ |
| { type: Directive, args: [{ selector: '[formGroupName]', providers: [formGroupNameProvider] },] } |
| ]; |
| /** @nocollapse */ |
| FormGroupName.ctorParameters = () => [ |
| { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] } |
| ]; |
| FormGroupName.propDecorators = { |
| name: [{ type: Input, args: ['formGroupName',] }] |
| }; |
| /** @type {?} */ |
| const formArrayNameProvider = { |
| provide: ControlContainer, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => FormArrayName)) |
| }; |
| /** |
| * \@description |
| * |
| * Syncs a nested `FormArray` to a DOM element. |
| * |
| * This directive is designed to be used with a parent `FormGroupDirective` (selector: |
| * `[formGroup]`). |
| * |
| * It accepts the string name of the nested `FormArray` you want to link, and |
| * will look for a `FormArray` registered with that name in the parent |
| * `FormGroup` instance you passed into `FormGroupDirective`. |
| * |
| * @see [Reactive Forms Guide](guide/reactive-forms) |
| * @see `AbstractControl` |
| * |
| * \@usageNotes |
| * |
| * ### Example |
| * |
| * {\@example forms/ts/nestedFormArray/nested_form_array_example.ts region='Component'} |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@publicApi |
| */ |
| class FormArrayName extends ControlContainer { |
| /** |
| * @param {?} parent |
| * @param {?} validators |
| * @param {?} asyncValidators |
| */ |
| constructor(parent, validators, asyncValidators) { |
| super(); |
| this._parent = parent; |
| this._validators = validators; |
| this._asyncValidators = asyncValidators; |
| } |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs are initialized. For internal use only. |
| * |
| * @throws If the directive does not have a valid parent. |
| * @return {?} |
| */ |
| ngOnInit() { |
| this._checkParentType(); |
| (/** @type {?} */ (this.formDirective)).addFormArray(this); |
| } |
| /** |
| * \@description |
| * A lifecycle method called before the directive's instance is destroyed. For internal use only. |
| * @return {?} |
| */ |
| ngOnDestroy() { |
| if (this.formDirective) { |
| this.formDirective.removeFormArray(this); |
| } |
| } |
| /** |
| * \@description |
| * The `FormArray` bound to this directive. |
| * @return {?} |
| */ |
| get control() { return (/** @type {?} */ (this.formDirective)).getFormArray(this); } |
| /** |
| * \@description |
| * The top-level directive for this group if present, otherwise null. |
| * @return {?} |
| */ |
| get formDirective() { |
| return this._parent ? (/** @type {?} */ (this._parent.formDirective)) : null; |
| } |
| /** |
| * \@description |
| * Returns an array that represents the path from the top-level form to this control. |
| * Each index is the string name of the control on that level. |
| * @return {?} |
| */ |
| get path() { return controlPath(this.name, this._parent); } |
| /** |
| * \@description |
| * Synchronous validator function composed of all the synchronous validators registered with this |
| * directive. |
| * @return {?} |
| */ |
| get validator() { return composeValidators(this._validators); } |
| /** |
| * \@description |
| * Async validator function composed of all the async validators registered with this directive. |
| * @return {?} |
| */ |
| get asyncValidator() { |
| return composeAsyncValidators(this._asyncValidators); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _checkParentType() { |
| if (_hasInvalidParent(this._parent)) { |
| ReactiveErrors.arrayParentException(); |
| } |
| } |
| } |
| FormArrayName.decorators = [ |
| { type: Directive, args: [{ selector: '[formArrayName]', providers: [formArrayNameProvider] },] } |
| ]; |
| /** @nocollapse */ |
| FormArrayName.ctorParameters = () => [ |
| { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] } |
| ]; |
| FormArrayName.propDecorators = { |
| name: [{ type: Input, args: ['formArrayName',] }] |
| }; |
| /** |
| * @param {?} parent |
| * @return {?} |
| */ |
| function _hasInvalidParent(parent) { |
| return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) && |
| !(parent instanceof FormArrayName); |
| } |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const controlNameBinding = { |
| provide: NgControl, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => FormControlName)) |
| }; |
| /** |
| * \@description |
| * Syncs a `FormControl` in an existing `FormGroup` to a form control |
| * element by name. |
| * |
| * @see [Reactive Forms Guide](guide/reactive-forms) |
| * @see `FormControl` |
| * @see `AbstractControl` |
| * |
| * \@usageNotes |
| * |
| * ### Register `FormControl` within a group |
| * |
| * The following example shows how to register multiple form controls within a form group |
| * and set their value. |
| * |
| * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'} |
| * |
| * To see `formControlName` examples with different form control types, see: |
| * |
| * * Radio buttons: `RadioControlValueAccessor` |
| * * Selects: `SelectControlValueAccessor` |
| * |
| * ### Use with ngModel |
| * |
| * Support for using the `ngModel` input property and `ngModelChange` event with reactive |
| * form directives has been deprecated in Angular v6 and will be removed in Angular v7. |
| * |
| * Now deprecated: |
| * |
| * ```html |
| * <form [formGroup]="form"> |
| * <input formControlName="first" [(ngModel)]="value"> |
| * </form> |
| * ``` |
| * |
| * ```ts |
| * this.value = 'some value'; |
| * ``` |
| * |
| * This has been deprecated for a few reasons. First, developers have found this pattern |
| * confusing. It seems like the actual `ngModel` directive is being used, but in fact it's |
| * an input/output property named `ngModel` on the reactive form directive that simply |
| * approximates (some of) its behavior. Specifically, it allows getting/setting the value |
| * and intercepting value events. However, some of `ngModel`'s other features - like |
| * delaying updates with`ngModelOptions` or exporting the directive - simply don't work, |
| * which has understandably caused some confusion. |
| * |
| * In addition, this pattern mixes template-driven and reactive forms strategies, which |
| * we generally don't recommend because it doesn't take advantage of the full benefits of |
| * either strategy. Setting the value in the template violates the template-agnostic |
| * principles behind reactive forms, whereas adding a `FormControl`/`FormGroup` layer in |
| * the class removes the convenience of defining forms in the template. |
| * |
| * To update your code before v7, you'll want to decide whether to stick with reactive form |
| * directives (and get/set values using reactive forms patterns) or switch over to |
| * template-driven directives. |
| * |
| * After (choice 1 - use reactive forms): |
| * |
| * ```html |
| * <form [formGroup]="form"> |
| * <input formControlName="first"> |
| * </form> |
| * ``` |
| * |
| * ```ts |
| * this.form.get('first').setValue('some value'); |
| * ``` |
| * |
| * After (choice 2 - use template-driven forms): |
| * |
| * ```html |
| * <input [(ngModel)]="value"> |
| * ``` |
| * |
| * ```ts |
| * this.value = 'some value'; |
| * ``` |
| * |
| * By default, when you use this pattern, you will see a deprecation warning once in dev |
| * mode. You can choose to silence this warning by providing a config for |
| * `ReactiveFormsModule` at import time: |
| * |
| * ```ts |
| * imports: [ |
| * ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'}) |
| * ] |
| * ``` |
| * |
| * Alternatively, you can choose to surface a separate warning for each instance of this |
| * pattern with a config value of `"always"`. This may help to track down where in the code |
| * the pattern is being used as the code is being updated. |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@publicApi |
| */ |
| class FormControlName extends NgControl { |
| /** |
| * @param {?} parent |
| * @param {?} validators |
| * @param {?} asyncValidators |
| * @param {?} valueAccessors |
| * @param {?} _ngModelWarningConfig |
| */ |
| constructor(parent, validators, asyncValidators, valueAccessors, _ngModelWarningConfig) { |
| super(); |
| this._ngModelWarningConfig = _ngModelWarningConfig; |
| this._added = false; |
| /** |
| * @deprecated as of v6 |
| */ |
| this.update = new EventEmitter(); |
| /** |
| * \@description |
| * Instance property used to track whether an ngModel warning has been sent out for this |
| * particular FormControlName instance. Used to support warning config of "always". |
| * |
| * \@internal |
| */ |
| this._ngModelWarningSent = false; |
| this._parent = parent; |
| this._rawValidators = validators || []; |
| this._rawAsyncValidators = asyncValidators || []; |
| this.valueAccessor = selectValueAccessor(this, valueAccessors); |
| } |
| /** |
| * \@description |
| * Triggers a warning that this input should not be used with reactive forms. |
| * @param {?} isDisabled |
| * @return {?} |
| */ |
| set isDisabled(isDisabled) { ReactiveErrors.disabledAttrWarning(); } |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs change. For internal use only. |
| * |
| * @param {?} changes A object of key/value pairs for the set of changed inputs. |
| * @return {?} |
| */ |
| ngOnChanges(changes) { |
| if (!this._added) |
| this._setUpControl(); |
| if (isPropertyUpdated(changes, this.viewModel)) { |
| _ngModelWarning('formControlName', FormControlName, this, this._ngModelWarningConfig); |
| this.viewModel = this.model; |
| this.formDirective.updateModel(this, this.model); |
| } |
| } |
| /** |
| * \@description |
| * Lifecycle method called before the directive's instance is destroyed. For internal use only. |
| * @return {?} |
| */ |
| ngOnDestroy() { |
| if (this.formDirective) { |
| this.formDirective.removeControl(this); |
| } |
| } |
| /** |
| * \@description |
| * Sets the new value for the view model and emits an `ngModelChange` event. |
| * |
| * @param {?} newValue The new value for the view model. |
| * @return {?} |
| */ |
| viewToModelUpdate(newValue) { |
| this.viewModel = newValue; |
| this.update.emit(newValue); |
| } |
| /** |
| * \@description |
| * Returns an array that represents the path from the top-level form to this control. |
| * Each index is the string name of the control on that level. |
| * @return {?} |
| */ |
| get path() { return controlPath(this.name, (/** @type {?} */ (this._parent))); } |
| /** |
| * \@description |
| * The top-level directive for this group if present, otherwise null. |
| * @return {?} |
| */ |
| get formDirective() { return this._parent ? this._parent.formDirective : null; } |
| /** |
| * \@description |
| * Synchronous validator function composed of all the synchronous validators |
| * registered with this directive. |
| * @return {?} |
| */ |
| get validator() { return composeValidators(this._rawValidators); } |
| /** |
| * \@description |
| * Async validator function composed of all the async validators registered with this |
| * directive. |
| * @return {?} |
| */ |
| get asyncValidator() { |
| return (/** @type {?} */ (composeAsyncValidators(this._rawAsyncValidators))); |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _checkParentType() { |
| if (!(this._parent instanceof FormGroupName) && |
| this._parent instanceof AbstractFormGroupDirective) { |
| ReactiveErrors.ngModelGroupException(); |
| } |
| else if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) && |
| !(this._parent instanceof FormArrayName)) { |
| ReactiveErrors.controlParentException(); |
| } |
| } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _setUpControl() { |
| this._checkParentType(); |
| ((/** @type {?} */ (this))).control = this.formDirective.addControl(this); |
| if (this.control.disabled && (/** @type {?} */ (this.valueAccessor)).setDisabledState) { |
| (/** @type {?} */ ((/** @type {?} */ (this.valueAccessor)).setDisabledState))(true); |
| } |
| this._added = true; |
| } |
| } |
| /** |
| * \@description |
| * Static property used to track whether any ngModel warnings have been sent across |
| * all instances of FormControlName. Used to support warning config of "once". |
| * |
| * \@internal |
| */ |
| FormControlName._ngModelWarningSentOnce = false; |
| FormControlName.decorators = [ |
| { type: Directive, args: [{ selector: '[formControlName]', providers: [controlNameBinding] },] } |
| ]; |
| /** @nocollapse */ |
| FormControlName.ctorParameters = () => [ |
| { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }, |
| { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] }] }, |
| { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NG_MODEL_WITH_FORM_CONTROL_WARNING,] }] } |
| ]; |
| FormControlName.propDecorators = { |
| name: [{ type: Input, args: ['formControlName',] }], |
| isDisabled: [{ type: Input, args: ['disabled',] }], |
| model: [{ type: Input, args: ['ngModel',] }], |
| update: [{ type: Output, args: ['ngModelChange',] }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * \@description |
| * Provider which adds `RequiredValidator` to the `NG_VALIDATORS` multi-provider list. |
| * @type {?} |
| */ |
| const REQUIRED_VALIDATOR = { |
| provide: NG_VALIDATORS, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => RequiredValidator)), |
| multi: true |
| }; |
| /** |
| * \@description |
| * Provider which adds `CheckboxRequiredValidator` to the `NG_VALIDATORS` multi-provider list. |
| * @type {?} |
| */ |
| const CHECKBOX_REQUIRED_VALIDATOR = { |
| provide: NG_VALIDATORS, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => CheckboxRequiredValidator)), |
| multi: true |
| }; |
| /** |
| * \@description |
| * A directive that adds the `required` validator to any controls marked with the |
| * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list. |
| * |
| * @see [Form Validation](guide/form-validation) |
| * |
| * \@usageNotes |
| * |
| * ### Adding a required validator using template-driven forms |
| * |
| * ``` |
| * <input name="fullName" ngModel required> |
| * ``` |
| * |
| * \@ngModule FormsModule |
| * \@ngModule ReactiveFormsModule |
| * \@publicApi |
| */ |
| class RequiredValidator { |
| /** |
| * \@description |
| * Tracks changes to the required attribute bound to this directive. |
| * @return {?} |
| */ |
| get required() { return this._required; } |
| /** |
| * @param {?} value |
| * @return {?} |
| */ |
| set required(value) { |
| this._required = value != null && value !== false && `${value}` !== 'false'; |
| if (this._onChange) |
| this._onChange(); |
| } |
| /** |
| * \@description |
| * Method that validates whether the control is empty. |
| * Returns the validation result if enabled, otherwise null. |
| * @param {?} control |
| * @return {?} |
| */ |
| validate(control) { |
| return this.required ? Validators.required(control) : null; |
| } |
| /** |
| * \@description |
| * Registers a callback function to call when the validator inputs change. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnValidatorChange(fn) { this._onChange = fn; } |
| } |
| RequiredValidator.decorators = [ |
| { type: Directive, args: [{ |
| selector: ':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]', |
| providers: [REQUIRED_VALIDATOR], |
| host: { '[attr.required]': 'required ? "" : null' } |
| },] } |
| ]; |
| RequiredValidator.propDecorators = { |
| required: [{ type: Input }] |
| }; |
| /** |
| * A Directive that adds the `required` validator to checkbox controls marked with the |
| * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list. |
| * |
| * @see [Form Validation](guide/form-validation) |
| * |
| * \@usageNotes |
| * |
| * ### Adding a required checkbox validator using template-driven forms |
| * |
| * The following example shows how to add a checkbox required validator to an input attached to an ngModel binding. |
| * |
| * ``` |
| * <input type="checkbox" name="active" ngModel required> |
| * ``` |
| * |
| * \@publicApi |
| * \@ngModule FormsModule |
| * \@ngModule ReactiveFormsModule |
| */ |
| class CheckboxRequiredValidator extends RequiredValidator { |
| /** |
| * \@description |
| * Method that validates whether or not the checkbox has been checked. |
| * Returns the validation result if enabled, otherwise null. |
| * @param {?} control |
| * @return {?} |
| */ |
| validate(control) { |
| return this.required ? Validators.requiredTrue(control) : null; |
| } |
| } |
| CheckboxRequiredValidator.decorators = [ |
| { type: Directive, args: [{ |
| selector: 'input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]', |
| providers: [CHECKBOX_REQUIRED_VALIDATOR], |
| host: { '[attr.required]': 'required ? "" : null' } |
| },] } |
| ]; |
| /** |
| * \@description |
| * Provider which adds `EmailValidator` to the `NG_VALIDATORS` multi-provider list. |
| * @type {?} |
| */ |
| const EMAIL_VALIDATOR = { |
| provide: NG_VALIDATORS, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => EmailValidator)), |
| multi: true |
| }; |
| /** |
| * A directive that adds the `email` validator to controls marked with the |
| * `email` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list. |
| * |
| * @see [Form Validation](guide/form-validation) |
| * |
| * \@usageNotes |
| * |
| * ### Adding an email validator |
| * |
| * The following example shows how to add an email validator to an input attached to an ngModel binding. |
| * |
| * ``` |
| * <input type="email" name="email" ngModel email> |
| * <input type="email" name="email" ngModel email="true"> |
| * <input type="email" name="email" ngModel [email]="true"> |
| * ``` |
| * |
| * \@publicApi |
| * \@ngModule FormsModule |
| * \@ngModule ReactiveFormsModule |
| */ |
| class EmailValidator { |
| /** |
| * \@description |
| * Tracks changes to the email attribute bound to this directive. |
| * @param {?} value |
| * @return {?} |
| */ |
| set email(value) { |
| this._enabled = value === '' || value === true || value === 'true'; |
| if (this._onChange) |
| this._onChange(); |
| } |
| /** |
| * \@description |
| * Method that validates whether an email address is valid. |
| * Returns the validation result if enabled, otherwise null. |
| * @param {?} control |
| * @return {?} |
| */ |
| validate(control) { |
| return this._enabled ? Validators.email(control) : null; |
| } |
| /** |
| * \@description |
| * Registers a callback function to call when the validator inputs change. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnValidatorChange(fn) { this._onChange = fn; } |
| } |
| EmailValidator.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[email][formControlName],[email][formControl],[email][ngModel]', |
| providers: [EMAIL_VALIDATOR] |
| },] } |
| ]; |
| EmailValidator.propDecorators = { |
| email: [{ type: Input }] |
| }; |
| /** |
| * \@description |
| * Provider which adds `MinLengthValidator` to the `NG_VALIDATORS` multi-provider list. |
| * @type {?} |
| */ |
| const MIN_LENGTH_VALIDATOR = { |
| provide: NG_VALIDATORS, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => MinLengthValidator)), |
| multi: true |
| }; |
| /** |
| * A directive that adds minimum length validation to controls marked with the |
| * `minlength` attribute. The directive is provided with the `NG_VALIDATORS` mult-provider list. |
| * |
| * @see [Form Validation](guide/form-validation) |
| * |
| * \@usageNotes |
| * |
| * ### Adding a minimum length validator |
| * |
| * The following example shows how to add a minimum length validator to an input attached to an |
| * ngModel binding. |
| * |
| * ```html |
| * <input name="firstName" ngModel minlength="4"> |
| * ``` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class MinLengthValidator { |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs change. For internal use |
| * only. |
| * |
| * @param {?} changes A object of key/value pairs for the set of changed inputs. |
| * @return {?} |
| */ |
| ngOnChanges(changes) { |
| if ('minlength' in changes) { |
| this._createValidator(); |
| if (this._onChange) |
| this._onChange(); |
| } |
| } |
| /** |
| * \@description |
| * Method that validates whether the value meets a minimum length |
| * requirement. Returns the validation result if enabled, otherwise null. |
| * @param {?} control |
| * @return {?} |
| */ |
| validate(control) { |
| return this.minlength == null ? null : this._validator(control); |
| } |
| /** |
| * \@description |
| * Registers a callback function to call when the validator inputs change. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnValidatorChange(fn) { this._onChange = fn; } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _createValidator() { |
| this._validator = Validators.minLength(parseInt(this.minlength, 10)); |
| } |
| } |
| MinLengthValidator.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]', |
| providers: [MIN_LENGTH_VALIDATOR], |
| host: { '[attr.minlength]': 'minlength ? minlength : null' } |
| },] } |
| ]; |
| MinLengthValidator.propDecorators = { |
| minlength: [{ type: Input }] |
| }; |
| /** |
| * \@description |
| * Provider which adds `MaxLengthValidator` to the `NG_VALIDATORS` multi-provider list. |
| * @type {?} |
| */ |
| const MAX_LENGTH_VALIDATOR = { |
| provide: NG_VALIDATORS, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => MaxLengthValidator)), |
| multi: true |
| }; |
| /** |
| * A directive that adds max length validation to controls marked with the |
| * `maxlength` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list. |
| * |
| * @see [Form Validation](guide/form-validation) |
| * |
| * \@usageNotes |
| * |
| * ### Adding a maximum length validator |
| * |
| * The following example shows how to add a maximum length validator to an input attached to an |
| * ngModel binding. |
| * |
| * ```html |
| * <input name="firstName" ngModel maxlength="25"> |
| * ``` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class MaxLengthValidator { |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs change. For internal use |
| * only. |
| * |
| * @param {?} changes A object of key/value pairs for the set of changed inputs. |
| * @return {?} |
| */ |
| ngOnChanges(changes) { |
| if ('maxlength' in changes) { |
| this._createValidator(); |
| if (this._onChange) |
| this._onChange(); |
| } |
| } |
| /** |
| * \@description |
| * Method that validates whether the value exceeds |
| * the maximum length requirement. |
| * @param {?} control |
| * @return {?} |
| */ |
| validate(control) { |
| return this.maxlength != null ? this._validator(control) : null; |
| } |
| /** |
| * \@description |
| * Registers a callback function to call when the validator inputs change. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnValidatorChange(fn) { this._onChange = fn; } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _createValidator() { |
| this._validator = Validators.maxLength(parseInt(this.maxlength, 10)); |
| } |
| } |
| MaxLengthValidator.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]', |
| providers: [MAX_LENGTH_VALIDATOR], |
| host: { '[attr.maxlength]': 'maxlength ? maxlength : null' } |
| },] } |
| ]; |
| MaxLengthValidator.propDecorators = { |
| maxlength: [{ type: Input }] |
| }; |
| /** |
| * \@description |
| * Provider which adds `PatternValidator` to the `NG_VALIDATORS` multi-provider list. |
| * @type {?} |
| */ |
| const PATTERN_VALIDATOR = { |
| provide: NG_VALIDATORS, |
| useExisting: forwardRef((/** |
| * @return {?} |
| */ |
| () => PatternValidator)), |
| multi: true |
| }; |
| /** |
| * \@description |
| * A directive that adds regex pattern validation to controls marked with the |
| * `pattern` attribute. The regex must match the entire control value. |
| * The directive is provided with the `NG_VALIDATORS` multi-provider list. |
| * |
| * @see [Form Validation](guide/form-validation) |
| * |
| * \@usageNotes |
| * |
| * ### Adding a pattern validator |
| * |
| * The following example shows how to add a pattern validator to an input attached to an |
| * ngModel binding. |
| * |
| * ```html |
| * <input name="firstName" ngModel pattern="[a-zA-Z ]*"> |
| * ``` |
| * |
| * \@ngModule ReactiveFormsModule |
| * \@ngModule FormsModule |
| * \@publicApi |
| */ |
| class PatternValidator { |
| /** |
| * \@description |
| * A lifecycle method called when the directive's inputs change. For internal use |
| * only. |
| * |
| * @param {?} changes A object of key/value pairs for the set of changed inputs. |
| * @return {?} |
| */ |
| ngOnChanges(changes) { |
| if ('pattern' in changes) { |
| this._createValidator(); |
| if (this._onChange) |
| this._onChange(); |
| } |
| } |
| /** |
| * \@description |
| * Method that validates whether the value matches the |
| * the pattern requirement. |
| * @param {?} control |
| * @return {?} |
| */ |
| validate(control) { return this._validator(control); } |
| /** |
| * \@description |
| * Registers a callback function to call when the validator inputs change. |
| * |
| * @param {?} fn The callback function |
| * @return {?} |
| */ |
| registerOnValidatorChange(fn) { this._onChange = fn; } |
| /** |
| * @private |
| * @return {?} |
| */ |
| _createValidator() { this._validator = Validators.pattern(this.pattern); } |
| } |
| PatternValidator.decorators = [ |
| { type: Directive, args: [{ |
| selector: '[pattern][formControlName],[pattern][formControl],[pattern][ngModel]', |
| providers: [PATTERN_VALIDATOR], |
| host: { '[attr.pattern]': 'pattern ? pattern : null' } |
| },] } |
| ]; |
| PatternValidator.propDecorators = { |
| pattern: [{ type: Input }] |
| }; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** @type {?} */ |
| const SHARED_FORM_DIRECTIVES = [ |
| ɵNgNoValidate, |
| NgSelectOption, |
| ɵNgSelectMultipleOption, |
| DefaultValueAccessor, |
| NumberValueAccessor, |
| RangeValueAccessor, |
| CheckboxControlValueAccessor, |
| SelectControlValueAccessor, |
| SelectMultipleControlValueAccessor, |
| RadioControlValueAccessor, |
| NgControlStatus, |
| NgControlStatusGroup, |
| RequiredValidator, |
| MinLengthValidator, |
| MaxLengthValidator, |
| PatternValidator, |
| CheckboxRequiredValidator, |
| EmailValidator, |
| ]; |
| /** @type {?} */ |
| const TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm, NgFormSelectorWarning]; |
| /** @type {?} */ |
| const REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName]; |
| /** |
| * Internal module used for sharing directives between FormsModule and ReactiveFormsModule |
| */ |
| class ɵInternalFormsSharedModule { |
| } |
| ɵInternalFormsSharedModule.decorators = [ |
| { type: NgModule, args: [{ |
| declarations: SHARED_FORM_DIRECTIVES, |
| exports: SHARED_FORM_DIRECTIVES, |
| },] } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * @param {?} options |
| * @return {?} |
| */ |
| function isAbstractControlOptions(options) { |
| return ((/** @type {?} */ (options))).asyncValidators !== undefined || |
| ((/** @type {?} */ (options))).validators !== undefined || |
| ((/** @type {?} */ (options))).updateOn !== undefined; |
| } |
| /** |
| * \@description |
| * Creates an `AbstractControl` from a user-specified configuration. |
| * |
| * The `FormBuilder` provides syntactic sugar that shortens creating instances of a `FormControl`, |
| * `FormGroup`, or `FormArray`. It reduces the amount of boilerplate needed to build complex |
| * forms. |
| * |
| * @see [Reactive Forms Guide](/guide/reactive-forms) |
| * |
| * \@publicApi |
| */ |
| class FormBuilder { |
| /** |
| * \@description |
| * Construct a new `FormGroup` instance. |
| * |
| * @param {?} controlsConfig A collection of child controls. The key for each child is the name |
| * under which it is registered. |
| * |
| * @param {?=} options Configuration options object for the `FormGroup`. The object can |
| * have two shapes: |
| * |
| * 1) `AbstractControlOptions` object (preferred), which consists of: |
| * * `validators`: A synchronous validator function, or an array of validator functions |
| * * `asyncValidators`: A single async validator or array of async validator functions |
| * * `updateOn`: The event upon which the control should be updated (options: 'change' | 'blur' | |
| * submit') |
| * |
| * 2) Legacy configuration object, which consists of: |
| * * `validator`: A synchronous validator function, or an array of validator functions |
| * * `asyncValidator`: A single async validator or array of async validator functions |
| * |
| * @return {?} |
| */ |
| group(controlsConfig, options = null) { |
| /** @type {?} */ |
| const controls = this._reduceControls(controlsConfig); |
| /** @type {?} */ |
| let validators = null; |
| /** @type {?} */ |
| let asyncValidators = null; |
| /** @type {?} */ |
| let updateOn = undefined; |
| if (options != null) { |
| if (isAbstractControlOptions(options)) { |
| // `options` are `AbstractControlOptions` |
| validators = options.validators != null ? options.validators : null; |
| asyncValidators = options.asyncValidators != null ? options.asyncValidators : null; |
| updateOn = options.updateOn != null ? options.updateOn : undefined; |
| } |
| else { |
| // `options` are legacy form group options |
| validators = options['validator'] != null ? options['validator'] : null; |
| asyncValidators = options['asyncValidator'] != null ? options['asyncValidator'] : null; |
| } |
| } |
| return new FormGroup(controls, { asyncValidators, updateOn, validators }); |
| } |
| /** |
| * \@description |
| * Construct a new `FormControl` with the given state, validators and options. |
| * |
| * \@usageNotes |
| * |
| * ### Initialize a control as disabled |
| * |
| * The following example returns a control with an initial value in a disabled state. |
| * |
| * <code-example path="forms/ts/formBuilder/form_builder_example.ts" |
| * linenums="false" region="disabled-control"> |
| * </code-example> |
| * @param {?} formState Initializes the control with an initial state value, or |
| * with an object that contains both a value and a disabled status. |
| * |
| * @param {?=} validatorOrOpts A synchronous validator function, or an array of |
| * such functions, or an `AbstractControlOptions` object that contains |
| * validation functions and a validation trigger. |
| * |
| * @param {?=} asyncValidator A single async validator or array of async validator |
| * functions. |
| * |
| * @return {?} |
| */ |
| control(formState, validatorOrOpts, asyncValidator) { |
| return new FormControl(formState, validatorOrOpts, asyncValidator); |
| } |
| /** |
| * Constructs a new `FormArray` from the given array of configurations, |
| * validators and options. |
| * |
| * @param {?} controlsConfig An array of child controls or control configs. Each |
| * child control is given an index when it is registered. |
| * |
| * @param {?=} validatorOrOpts A synchronous validator function, or an array of |
| * such functions, or an `AbstractControlOptions` object that contains |
| * validation functions and a validation trigger. |
| * |
| * @param {?=} asyncValidator A single async validator or array of async validator |
| * functions. |
| * @return {?} |
| */ |
| array(controlsConfig, validatorOrOpts, asyncValidator) { |
| /** @type {?} */ |
| const controls = controlsConfig.map((/** |
| * @param {?} c |
| * @return {?} |
| */ |
| c => this._createControl(c))); |
| return new FormArray(controls, validatorOrOpts, asyncValidator); |
| } |
| /** |
| * \@internal |
| * @param {?} controlsConfig |
| * @return {?} |
| */ |
| _reduceControls(controlsConfig) { |
| /** @type {?} */ |
| const controls = {}; |
| Object.keys(controlsConfig).forEach((/** |
| * @param {?} controlName |
| * @return {?} |
| */ |
| controlName => { |
| controls[controlName] = this._createControl(controlsConfig[controlName]); |
| })); |
| return controls; |
| } |
| /** |
| * \@internal |
| * @param {?} controlConfig |
| * @return {?} |
| */ |
| _createControl(controlConfig) { |
| if (controlConfig instanceof FormControl || controlConfig instanceof FormGroup || |
| controlConfig instanceof FormArray) { |
| return controlConfig; |
| } |
| else if (Array.isArray(controlConfig)) { |
| /** @type {?} */ |
| const value = controlConfig[0]; |
| /** @type {?} */ |
| const validator = controlConfig.length > 1 ? controlConfig[1] : null; |
| /** @type {?} */ |
| const asyncValidator = controlConfig.length > 2 ? controlConfig[2] : null; |
| return this.control(value, validator, asyncValidator); |
| } |
| else { |
| return this.control(controlConfig); |
| } |
| } |
| } |
| FormBuilder.decorators = [ |
| { type: Injectable } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * \@publicApi |
| * @type {?} |
| */ |
| const VERSION = new Version('8.1.1'); |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| /** |
| * Exports the required providers and directives for template-driven forms, |
| * making them available for import by NgModules that import this module. |
| * |
| * @see [Forms Guide](/guide/forms) |
| * |
| * \@publicApi |
| */ |
| class FormsModule { |
| /** |
| * \@description |
| * Provides options for configuring the template-driven forms module. |
| * |
| * @param {?} opts An object of configuration options |
| * * `warnOnDeprecatedNgFormSelector` Configures when to emit a warning when the deprecated |
| * `ngForm` selector is used. |
| * @return {?} |
| */ |
| static withConfig(opts) { |
| return { |
| ngModule: FormsModule, |
| providers: [{ provide: NG_FORM_SELECTOR_WARNING, useValue: opts.warnOnDeprecatedNgFormSelector }] |
| }; |
| } |
| } |
| FormsModule.decorators = [ |
| { type: NgModule, args: [{ |
| declarations: TEMPLATE_DRIVEN_DIRECTIVES, |
| providers: [RadioControlRegistry], |
| exports: [ɵInternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES] |
| },] } |
| ]; |
| /** |
| * Exports the required infrastructure and directives for reactive forms, |
| * making them available for import by NgModules that import this module. |
| * @see [Forms](guide/reactive-forms) |
| * |
| * @see [Reactive Forms Guide](/guide/reactive-forms) |
| * |
| * \@publicApi |
| */ |
| class ReactiveFormsModule { |
| /** |
| * \@description |
| * Provides options for configuring the reactive forms module. |
| * |
| * @param {?} opts An object of configuration options |
| * * `warnOnNgModelWithFormControl` Configures when to emit a warning when an `ngModel` |
| * binding is used with reactive form directives. |
| * @return {?} |
| */ |
| static withConfig(opts) { |
| return { |
| ngModule: ReactiveFormsModule, |
| providers: [{ |
| provide: NG_MODEL_WITH_FORM_CONTROL_WARNING, |
| useValue: opts.warnOnNgModelWithFormControl |
| }] |
| }; |
| } |
| } |
| ReactiveFormsModule.decorators = [ |
| { type: NgModule, args: [{ |
| declarations: [REACTIVE_DRIVEN_DIRECTIVES], |
| providers: [FormBuilder, RadioControlRegistry], |
| exports: [ɵInternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES] |
| },] } |
| ]; |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| |
| /** |
| * @fileoverview added by tsickle |
| * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc |
| */ |
| |
| /** |
| * Generated bundle index. Do not edit. |
| */ |
| |
| export { ɵInternalFormsSharedModule as ɵangular_packages_forms_forms_d, ɵInternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES as ɵangular_packages_forms_forms_c, SHARED_FORM_DIRECTIVES as ɵangular_packages_forms_forms_a, TEMPLATE_DRIVEN_DIRECTIVES as ɵangular_packages_forms_forms_b, CHECKBOX_VALUE_ACCESSOR as ɵangular_packages_forms_forms_e, DEFAULT_VALUE_ACCESSOR as ɵangular_packages_forms_forms_f, AbstractControlStatus as ɵangular_packages_forms_forms_g, ngControlStatusHost as ɵangular_packages_forms_forms_h, formDirectiveProvider as ɵangular_packages_forms_forms_i, NG_FORM_SELECTOR_WARNING as ɵangular_packages_forms_forms_j, formControlBinding as ɵangular_packages_forms_forms_k, modelGroupProvider as ɵangular_packages_forms_forms_l, ɵNgNoValidate as ɵangular_packages_forms_forms_z, ɵNgNoValidate, NUMBER_VALUE_ACCESSOR as ɵangular_packages_forms_forms_m, RADIO_VALUE_ACCESSOR as ɵangular_packages_forms_forms_n, RadioControlRegistry as ɵangular_packages_forms_forms_o, RANGE_VALUE_ACCESSOR as ɵangular_packages_forms_forms_p, NG_MODEL_WITH_FORM_CONTROL_WARNING as ɵangular_packages_forms_forms_q, formControlBinding$1 as ɵangular_packages_forms_forms_r, controlNameBinding as ɵangular_packages_forms_forms_s, formDirectiveProvider$1 as ɵangular_packages_forms_forms_t, formArrayNameProvider as ɵangular_packages_forms_forms_v, formGroupNameProvider as ɵangular_packages_forms_forms_u, SELECT_VALUE_ACCESSOR as ɵangular_packages_forms_forms_w, ɵNgSelectMultipleOption as ɵangular_packages_forms_forms_y, ɵNgSelectMultipleOption, SELECT_MULTIPLE_VALUE_ACCESSOR as ɵangular_packages_forms_forms_x, CHECKBOX_REQUIRED_VALIDATOR as ɵangular_packages_forms_forms_bb, EMAIL_VALIDATOR as ɵangular_packages_forms_forms_bc, MAX_LENGTH_VALIDATOR as ɵangular_packages_forms_forms_be, MIN_LENGTH_VALIDATOR as ɵangular_packages_forms_forms_bd, PATTERN_VALIDATOR as ɵangular_packages_forms_forms_bf, REQUIRED_VALIDATOR as ɵangular_packages_forms_forms_ba, AbstractControlDirective, AbstractFormGroupDirective, CheckboxControlValueAccessor, ControlContainer, NG_VALUE_ACCESSOR, COMPOSITION_BUFFER_MODE, DefaultValueAccessor, NgControl, NgControlStatus, NgControlStatusGroup, NgForm, NgFormSelectorWarning, NgModel, NgModelGroup, NumberValueAccessor, RadioControlValueAccessor, RangeValueAccessor, FormControlDirective, FormControlName, FormGroupDirective, FormArrayName, FormGroupName, NgSelectOption, SelectControlValueAccessor, SelectMultipleControlValueAccessor, CheckboxRequiredValidator, EmailValidator, MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator, FormBuilder, AbstractControl, FormArray, FormControl, FormGroup, NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators, VERSION, FormsModule, ReactiveFormsModule }; |
| //# sourceMappingURL=forms.js.map |