| 
									
										
										
										
											2016-06-23 09:47:54 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  | import {Injectable} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {AsyncValidatorFn, ValidatorFn} from './directives/validators'; | 
					
						
							| 
									
										
										
										
											2016-06-22 14:56:10 -07:00
										 |  |  | import {AbstractControl, FormArray, FormControl, FormGroup} from './model'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2016-09-13 13:23:31 -07:00
										 |  |  |  * @whatItDoes Creates an {@link AbstractControl} from a user-specified configuration. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * It is essentially syntactic sugar that shortens the `new FormGroup()`, | 
					
						
							|  |  |  |  * `new FormControl()`, and `new FormArray()` boilerplate that can build up in larger | 
					
						
							|  |  |  |  * forms. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @howToUse | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-09-13 13:23:31 -07:00
										 |  |  |  * To use, inject `FormBuilder` into your component class. You can then call its methods | 
					
						
							|  |  |  |  * directly. | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-09-13 13:23:31 -07:00
										 |  |  |  * {@example forms/ts/formBuilder/form_builder_example.ts region='Component'} | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-09-13 13:23:31 -07:00
										 |  |  |  *  * **npm package**: `@angular/forms` | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  * **NgModule**: {@link ReactiveFormsModule} | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-08-17 07:44:39 -07:00
										 |  |  |  * @stable | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |  */ | 
					
						
							|  |  |  | @Injectable() | 
					
						
							|  |  |  | export class FormBuilder { | 
					
						
							|  |  |  |   /** | 
					
						
							| 
									
										
										
										
											2016-06-10 11:15:59 -07:00
										 |  |  |    * Construct a new {@link FormGroup} with the given map of configuration. | 
					
						
							| 
									
										
										
										
											2016-09-13 13:23:31 -07:00
										 |  |  |    * Valid keys for the `extra` parameter map are `validator` and `asyncValidator`. | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |    * | 
					
						
							| 
									
										
										
										
											2016-06-10 11:15:59 -07:00
										 |  |  |    * See the {@link FormGroup} constructor for more details. | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2017-04-17 11:13:30 -07:00
										 |  |  |   group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any}|null = null): FormGroup { | 
					
						
							| 
									
										
										
										
											2016-08-24 16:58:43 -07:00
										 |  |  |     const controls = this._reduceControls(controlsConfig); | 
					
						
							| 
									
										
										
										
											2017-03-02 09:37:01 -08:00
										 |  |  |     const validator: ValidatorFn = extra != null ? extra['validator'] : null; | 
					
						
							|  |  |  |     const asyncValidator: AsyncValidatorFn = extra != null ? extra['asyncValidator'] : null; | 
					
						
							| 
									
										
										
										
											2016-08-24 16:58:43 -07:00
										 |  |  |     return new FormGroup(controls, validator, asyncValidator); | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  |   /** | 
					
						
							| 
									
										
										
										
											2016-08-24 16:58:43 -07:00
										 |  |  |    * Construct a new {@link FormControl} with the given `formState`,`validator`, and | 
					
						
							|  |  |  |    * `asyncValidator`. | 
					
						
							| 
									
										
										
										
											2016-09-13 13:23:31 -07:00
										 |  |  |    * | 
					
						
							|  |  |  |    * `formState` can either be a standalone value for the form control or an object | 
					
						
							|  |  |  |    * that contains both a value and a disabled status. | 
					
						
							|  |  |  |    * | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2016-06-13 11:27:04 -07:00
										 |  |  |   control( | 
					
						
							| 
									
										
										
										
											2017-12-09 19:17:49 +01:00
										 |  |  |       formState: any, validator?: ValidatorFn|ValidatorFn[]|null, | 
					
						
							| 
									
										
										
										
											2017-04-17 11:13:30 -07:00
										 |  |  |       asyncValidator?: AsyncValidatorFn|AsyncValidatorFn[]|null): FormControl { | 
					
						
							| 
									
										
										
										
											2016-08-24 16:58:43 -07:00
										 |  |  |     return new FormControl(formState, validator, asyncValidator); | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							| 
									
										
										
										
											2016-09-13 13:23:31 -07:00
										 |  |  |    * Construct a {@link FormArray} from the given `controlsConfig` array of | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |    * configuration, with the given optional `validator` and `asyncValidator`. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |   array( | 
					
						
							| 
									
										
										
										
											2017-04-17 11:13:30 -07:00
										 |  |  |       controlsConfig: any[], validator?: ValidatorFn|null, | 
					
						
							|  |  |  |       asyncValidator?: AsyncValidatorFn|null): FormArray { | 
					
						
							| 
									
										
										
										
											2016-11-12 14:08:58 +01:00
										 |  |  |     const controls = controlsConfig.map(c => this._createControl(c)); | 
					
						
							| 
									
										
										
										
											2016-06-22 14:56:10 -07:00
										 |  |  |     return new FormArray(controls, validator, asyncValidator); | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** @internal */ | 
					
						
							| 
									
										
										
										
											2016-06-22 14:56:10 -07:00
										 |  |  |   _reduceControls(controlsConfig: {[k: string]: any}): {[key: string]: AbstractControl} { | 
					
						
							| 
									
										
										
										
											2016-11-12 14:08:58 +01:00
										 |  |  |     const controls: {[key: string]: AbstractControl} = {}; | 
					
						
							| 
									
										
										
										
											2016-10-03 16:46:05 -07:00
										 |  |  |     Object.keys(controlsConfig).forEach(controlName => { | 
					
						
							|  |  |  |       controls[controlName] = this._createControl(controlsConfig[controlName]); | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |     return controls; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** @internal */ | 
					
						
							| 
									
										
										
										
											2016-06-22 14:56:10 -07:00
										 |  |  |   _createControl(controlConfig: any): AbstractControl { | 
					
						
							|  |  |  |     if (controlConfig instanceof FormControl || controlConfig instanceof FormGroup || | 
					
						
							|  |  |  |         controlConfig instanceof FormArray) { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |       return controlConfig; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-19 13:42:39 -07:00
										 |  |  |     } 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; | 
					
						
							| 
									
										
										
										
											2016-06-08 15:36:24 -07:00
										 |  |  |       return this.control(value, validator, asyncValidator); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return this.control(controlConfig); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |