/** * @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 */ import {Injectable} from '@angular/core'; import {AsyncValidatorFn, ValidatorFn} from './directives/validators'; import {AbstractControl, FormArray, FormControl, FormGroup} from './model'; /** * @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) * */ @Injectable() export 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 extra An object of configuration options for the `FormGroup`. * * `validator`: A synchronous validator function, or an array of validator functions * * `asyncValidator`: A single async validator or array of async validator functions * */ group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any}|null = null): FormGroup { const controls = this._reduceControls(controlsConfig); const validator: ValidatorFn = extra != null ? extra['validator'] : null; const asyncValidator: AsyncValidatorFn = extra != null ? extra['asyncValidator'] : null; return new FormGroup(controls, validator, asyncValidator); } /** * @description * Construct 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 validator A synchronous validator function, or an array of synchronous validator * functions. * * @param asyncValidator A single async validator or array of async validator functions * * @usageNotes * * ### Initialize a control as disabled * * The following example returns a control with an initial value in a disabled state. * * * * */ control( formState: any, validator?: ValidatorFn|ValidatorFn[]|null, asyncValidator?: AsyncValidatorFn|AsyncValidatorFn[]|null): FormControl { return new FormControl(formState, validator, asyncValidator); } /** * @description * Construct a new `FormArray` instance. * * @param controlsConfig An array of child controls. The key for each child control is its index * in the array. * * @param validator A synchronous validator function, or an array of synchronous validator * functions. * * @param asyncValidator A single async validator or array of async validator functions */ array( controlsConfig: any[], validator?: ValidatorFn|ValidatorFn[]|null, asyncValidator?: AsyncValidatorFn|AsyncValidatorFn[]|null): FormArray { const controls = controlsConfig.map(c => this._createControl(c)); return new FormArray(controls, validator, asyncValidator); } /** @internal */ _reduceControls(controlsConfig: {[k: string]: any}): {[key: string]: AbstractControl} { const controls: {[key: string]: AbstractControl} = {}; Object.keys(controlsConfig).forEach(controlName => { controls[controlName] = this._createControl(controlsConfig[controlName]); }); return controls; } /** @internal */ _createControl(controlConfig: any): AbstractControl { if (controlConfig instanceof FormControl || controlConfig instanceof FormGroup || controlConfig instanceof FormArray) { return controlConfig; } else if (Array.isArray(controlConfig)) { const value = controlConfig[0]; const validator: ValidatorFn = controlConfig.length > 1 ? controlConfig[1] : null; const asyncValidator: AsyncValidatorFn = controlConfig.length > 2 ? controlConfig[2] : null; return this.control(value, validator, asyncValidator); } else { return this.control(controlConfig); } } }