diff --git a/modules/@angular/examples/forms/ts/ngModelGroup/e2e_test/ng_model_group_spec.ts b/modules/@angular/examples/forms/ts/ngModelGroup/e2e_test/ng_model_group_spec.ts new file mode 100644 index 0000000000..fc48df654f --- /dev/null +++ b/modules/@angular/examples/forms/ts/ngModelGroup/e2e_test/ng_model_group_spec.ts @@ -0,0 +1,41 @@ +/** + * @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('ngModelGroup example', () => { + afterEach(verifyNoBrowserErrors); + let inputs: ElementFinder; + let buttons: ElementFinder; + + beforeEach(() => { + browser.get('/forms/ts/ngModelGroup/index.html'); + inputs = element.all(by.css('input')); + buttons = element.all(by.css('button')); + }); + + 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 show the error when name is invalid', () => { + inputs.get(0).click(); + inputs.get(0).clear(); + inputs.get(0).sendKeys('a'); + + expect(element(by.css('p')).getText()).toEqual('Name is invalid.'); + }); + + it('should set the value when changing the domain model', () => { + buttons.get(1).click(); + expect(inputs.get(0).getAttribute('value')).toEqual('Bess'); + expect(inputs.get(1).getAttribute('value')).toEqual('Marvin'); + }); + +}); diff --git a/modules/@angular/examples/forms/ts/ngModelGroup/module.ts b/modules/@angular/examples/forms/ts/ngModelGroup/module.ts new file mode 100644 index 0000000000..ce06883c67 --- /dev/null +++ b/modules/@angular/examples/forms/ts/ngModelGroup/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 {FormsModule} from '@angular/forms'; +import {BrowserModule} from '@angular/platform-browser'; +import {NgModelGroupComp} from './ng_model_group_example'; + +@NgModule({ + imports: [BrowserModule, FormsModule], + declarations: [NgModelGroupComp], + bootstrap: [NgModelGroupComp] +}) +export class AppModule { +} diff --git a/modules/@angular/examples/forms/ts/ngModelGroup/ng_model_group_example.ts b/modules/@angular/examples/forms/ts/ngModelGroup/ng_model_group_example.ts new file mode 100644 index 0000000000..4c567c36ff --- /dev/null +++ b/modules/@angular/examples/forms/ts/ngModelGroup/ng_model_group_example.ts @@ -0,0 +1,41 @@ +/** + * @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} from '@angular/core'; +import {NgForm} from '@angular/forms'; + +@Component({ + selector: 'example-app', + template: ` +
+

Name is invalid.

+ +
+ + +
+ + + +
+ + + `, +}) +export class NgModelGroupComp { + name = {first: 'Nancy', last: 'Drew'}; + + onSubmit(f: NgForm) { + console.log(f.value); // {name: {first: 'Nancy', last: 'Drew'}, email: ''} + console.log(f.valid); // true + } + + setValue() { this.name = {first: 'Bess', last: 'Marvin'}; } +} +// #enddocregion diff --git a/modules/@angular/forms/src/directives/ng_model_group.ts b/modules/@angular/forms/src/directives/ng_model_group.ts index f1c42545fe..f463c3ec78 100644 --- a/modules/@angular/forms/src/directives/ng_model_group.ts +++ b/modules/@angular/forms/src/directives/ng_model_group.ts @@ -21,39 +21,27 @@ export const modelGroupProvider: any = { }; /** - * Creates and binds a model group to a DOM element. + * @whatItDoes Creates and binds a {@link FormGroup} instance to a DOM element. * - * This directive can only be used as a child of {@link NgForm}. + * @howToUse * - * ```typescript - * @Component({ - * selector: 'my-app', - * template: ` - *
- *

Angular forms Example

- *
- *
- *

Enter your name:

- *

First:

- *

Middle:

- *

Last:

- *
- *

Name value:

- *
{{ mgName.value | json }}
- *

Name is {{mgName?.valid ? "valid" : "invalid"}}

- *

What's your favorite food?

- *

- *

Form value

- *
{{ f.value | json }}
- *
- *
- * ` - * }) - * export class App {} - * ``` + * This directive can only be used as a child of {@link NgForm} (or in other words, + * within `
` tags). * - * This example declares a model group for a user's name. The value and validation state of - * this group can be accessed separately from the overall form. + * Use this directive if you'd like to create a sub-group within a form. This can + * come in handy if you want 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. + * + * Pass in the name you'd like this sub-group to have and it will become the key + * for the sub-group in the form's full value. You can also export the directive into + * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`). + * + * {@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'} + * + * * **npm package**: `@angular/forms` + * + * * **NgModule**: `FormsModule` * * @stable */