diff --git a/modules/@angular/examples/forms/ts/formBuilder/e2e_test/form_builder_spec.ts b/modules/@angular/examples/forms/ts/formBuilder/e2e_test/form_builder_spec.ts new file mode 100644 index 0000000000..80417ce408 --- /dev/null +++ b/modules/@angular/examples/forms/ts/formBuilder/e2e_test/form_builder_spec.ts @@ -0,0 +1,36 @@ +/** + * @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 {verifyNoBrowserErrors} from '../../../../_common/e2e_util'; + +describe('formBuilder example', () => { + afterEach(verifyNoBrowserErrors); + let inputs: ElementFinder; + let paragraphs: ElementFinder; + + beforeEach(() => { + browser.get('/forms/ts/formBuilder/index.html'); + inputs = element.all(by.css('input')); + paragraphs = element.all(by.css('p')); + }); + + it('should populate the UI with initial values', () => { + expect(inputs.get(0).getAttribute('value')).toEqual('Nancy'); + expect(inputs.get(1).getAttribute('value')).toEqual('Drew'); + }); + + it('should update the validation status', () => { + expect(paragraphs.get(1).getText()).toEqual('Validation status: VALID'); + + inputs.get(0).click(); + inputs.get(0).clear(); + inputs.get(0).sendKeys('a'); + expect(paragraphs.get(1).getText()).toEqual('Validation status: INVALID'); + }); + +}); diff --git a/modules/@angular/examples/forms/ts/formBuilder/form_builder_example.ts b/modules/@angular/examples/forms/ts/formBuilder/form_builder_example.ts new file mode 100644 index 0000000000..01a9690977 --- /dev/null +++ b/modules/@angular/examples/forms/ts/formBuilder/form_builder_example.ts @@ -0,0 +1,42 @@ +/** + * @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 + */ + +// #docregion Component +import {Component, Inject} from '@angular/core'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; + +@Component({ + selector: 'example-app', + template: ` +
+ +Value: {{ form.value | json }}
+Validation status: {{ form.status }}
+ ` +}) +export class FormBuilderComp { + form: FormGroup; + + constructor(@Inject(FormBuilder) fb: FormBuilder) { + this.form = fb.group({ + name: fb.group({ + first: ['Nancy', Validators.minLength(2)], + last: 'Drew', + }), + email: '', + }); + } +} +// #enddocregion diff --git a/modules/@angular/examples/forms/ts/formBuilder/module.ts b/modules/@angular/examples/forms/ts/formBuilder/module.ts new file mode 100644 index 0000000000..d34292d1d3 --- /dev/null +++ b/modules/@angular/examples/forms/ts/formBuilder/module.ts @@ -0,0 +1,20 @@ +/** + * @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 {NgModule} from '@angular/core'; +import {ReactiveFormsModule} from '@angular/forms'; +import {BrowserModule} from '@angular/platform-browser'; +import {FormBuilderComp} from './form_builder_example'; + +@NgModule({ + imports: [BrowserModule, ReactiveFormsModule], + declarations: [FormBuilderComp], + bootstrap: [FormBuilderComp] +}) +export class AppModule { +} diff --git a/modules/@angular/forms/src/form_builder.ts b/modules/@angular/forms/src/form_builder.ts index 6bc3d93da5..49ff12f56e 100644 --- a/modules/@angular/forms/src/form_builder.ts +++ b/modules/@angular/forms/src/form_builder.ts @@ -13,45 +13,23 @@ import {StringMapWrapper} from './facade/collection'; import {isArray, isPresent} from './facade/lang'; import {AbstractControl, FormArray, FormControl, FormGroup} from './model'; - - /** - * Creates a form object from a user-specified configuration. + * @whatItDoes Creates an {@link AbstractControl} from a user-specified configuration. * - * ```typescript - * @Component({ - * selector: 'my-app', - * template: ` - * - *{{value}}
- * `,
- * directives: [REACTIVE_FORM_DIRECTIVES]
- * })
- * export class App {
- * loginForm: FormGroup;
+ * It is essentially syntactic sugar that shortens the `new FormGroup()`,
+ * `new FormControl()`, and `new FormArray()` boilerplate that can build up in larger
+ * forms.
*
- * constructor(builder: FormBuilder) {
- * this.loginForm = builder.group({
- * login: ["", Validators.required],
- * passwordRetry: builder.group({
- * password: ["", Validators.required],
- * passwordConfirmation: ["", Validators.required, asyncValidator]
- * })
- * });
- * }
+ * @howToUse
*
- * get value(): string {
- * return JSON.stringify(this.loginForm.value, null, 2);
- * }
- * }
- * ```
+ * To use, inject `FormBuilder` into your component class. You can then call its methods
+ * directly.
+ *
+ * {@example forms/ts/formBuilder/form_builder_example.ts region='Component'}
+ *
+ * * **npm package**: `@angular/forms`
+ *
+ * * **NgModule**: {@link ReactiveFormsModule}
*
* @stable
*/
@@ -59,7 +37,7 @@ import {AbstractControl, FormArray, FormControl, FormGroup} from './model';
export class FormBuilder {
/**
* Construct a new {@link FormGroup} with the given map of configuration.
- * Valid keys for the `extra` parameter map are `optionals` and `validator`.
+ * Valid keys for the `extra` parameter map are `validator` and `asyncValidator`.
*
* See the {@link FormGroup} constructor for more details.
*/
@@ -74,6 +52,10 @@ export class FormBuilder {
/**
* Construct a new {@link FormControl} with the given `formState`,`validator`, and
* `asyncValidator`.
+ *
+ * `formState` can either be a standalone value for the form control or an object
+ * that contains both a value and a disabled status.
+ *
*/
control(
formState: Object, validator: ValidatorFn|ValidatorFn[] = null,
@@ -82,7 +64,7 @@ export class FormBuilder {
}
/**
- * Construct an array of {@link FormControl}s from the given `controlsConfig` array of
+ * Construct a {@link FormArray} from the given `controlsConfig` array of
* configuration, with the given optional `validator` and `asyncValidator`.
*/
array(