docs(forms): add select control examples (#11728)

This commit is contained in:
Kara 2016-09-19 16:25:33 -07:00 committed by Alex Eagle
parent 0621f07a2c
commit bf81b06a28
9 changed files with 233 additions and 11 deletions

View File

@ -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('reactiveSelectControl example', () => {
afterEach(verifyNoBrowserErrors);
let select: protractor.ElementFinder;
let options: protractor.ElementArrayFinder;
let p: protractor.ElementFinder;
beforeEach(() => {
browser.get('/forms/ts/reactiveSelectControl/index.html');
select = element(by.css('select'));
options = element.all(by.css('option'));
p = element(by.css('p'));
});
it('should populate the initial selection', () => {
expect(select.getAttribute('value')).toEqual('3: Object');
expect(options.get(3).getAttribute('selected')).toBe('true');
});
it('should update the model when the value changes in the UI', () => {
select.click();
options.get(0).click();
expect(p.getText()).toEqual('Form value: { "state": { "name": "Arizona", "abbrev": "AZ" } }');
});
});

View File

@ -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 {ReactiveSelectComp} from './reactive_select_control_example';
@NgModule({
imports: [BrowserModule, ReactiveFormsModule],
declarations: [ReactiveSelectComp],
bootstrap: [ReactiveSelectComp]
})
export class AppModule {
}

View File

@ -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 {FormControl, FormGroup} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form [formGroup]="form">
<select formControlName="state">
<option *ngFor="let state of states" [ngValue]="state">
{{ state.abbrev }}
</option>
</select>
</form>
<p>Form value: {{ form.value | json }}</p>
<!-- {state: {name: 'New York', abbrev: 'NY'} } -->
`,
})
export class ReactiveSelectComp {
states = [
{name: 'Arizona', abbrev: 'AZ'},
{name: 'California', abbrev: 'CA'},
{name: 'Colorado', abbrev: 'CO'},
{name: 'New York', abbrev: 'NY'},
{name: 'Pennsylvania', abbrev: 'PA'},
];
form = new FormGroup({
state: new FormControl(this.states[3]),
});
}
// #enddocregion

View File

@ -0,0 +1,34 @@
/**
* @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('selectControl example', () => {
afterEach(verifyNoBrowserErrors);
let select: protractor.ElementFinder;
let options: protractor.ElementArrayFinder;
let p: protractor.ElementFinder;
beforeEach(() => {
browser.get('/forms/ts/selectControl/index.html');
select = element(by.css('select'));
options = element.all(by.css('option'));
p = element(by.css('p'));
});
it('should initially select the placeholder option',
() => { expect(options.get(0).getAttribute('selected')).toBe('true'); });
it('should update the model when the value changes in the UI', () => {
select.click();
options.get(1).click();
expect(p.getText()).toEqual('Form value: { "state": { "name": "Arizona", "abbrev": "AZ" } }');
});
});

View File

@ -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 {SelectControlComp} from './select_control_example';
@NgModule({
imports: [BrowserModule, FormsModule],
declarations: [SelectControlComp],
bootstrap: [SelectControlComp]
})
export class AppModule {
}

View File

@ -0,0 +1,37 @@
/**
* @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';
@Component({
selector: 'example-app',
template: `
<form #f="ngForm">
<select name="state" ngModel>
<option value="" disabled>Choose a state</option>
<option *ngFor="let state of states" [ngValue]="state">
{{ state.abbrev }}
</option>
</select>
</form>
<p>Form value: {{ f.value | json }}</p>
<!-- example value: {state: {name: 'New York', abbrev: 'NY'} } -->
`,
})
export class SelectControlComp {
states = [
{name: 'Arizona', abbrev: 'AZ'},
{name: 'California', abbrev: 'CA'},
{name: 'Colorado', abbrev: 'CO'},
{name: 'New York', abbrev: 'NY'},
{name: 'Pennsylvania', abbrev: 'PA'},
];
}
// #enddocregion

View File

@ -76,6 +76,11 @@ const resolvedPromise = Promise.resolve(null);
*
* {@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
*
* To see `ngModel` examples with different form control types, see:
*
* * Radio buttons: {@link RadioControlValueAccessor}
* * Selects: {@link SelectControlValueAccessor}
*
* **npm package**: `@angular/forms`
*
* **NgModule**: `FormsModule`

View File

@ -67,9 +67,14 @@ export const controlNameBinding: any = {
*
* {@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
*
* * **npm package**: `@angular/forms`
* To see `formControlName` examples with different form control types, see:
*
* * **NgModule**: {@link ReactiveFormsModule}
* * Radio buttons: {@link RadioControlValueAccessor}
* * Selects: {@link SelectControlValueAccessor}
*
* **npm package**: `@angular/forms`
*
* **NgModule**: {@link ReactiveFormsModule}
*
* @stable
*/

View File

@ -30,13 +30,41 @@ function _extractId(valueString: string): string {
}
/**
* The accessor for writing a value and listening to changes on a select element.
* @whatItDoes Writes values and listens to changes on a select element.
*
* Note: We have to listen to the 'change' event because 'input' events aren't fired
* Used by {@link NgModel}, {@link FormControlDirective}, and {@link FormControlName}
* to keep the view synced with the {@link FormControl} model.
*
* @howToUse
*
* If you have imported the {@link FormsModule} or the {@link ReactiveFormsModule}, this
* value accessor will be active on any select control that has a form directive. You do
* **not** need to add a special selector to activate it.
*
* ### How to use select controls with form directives
*
* To use a select in a template-driven form, simply add an `ngModel` and a `name`
* attribute to the main `<select>` tag.
*
* If your option values are simple strings, you can bind to the normal `value` property
* on the option. If your option values happen to be objects (and you'd like to save the
* selection in your form as an object), use `ngValue` instead:
*
* {@example forms/ts/selectControl/select_control_example.ts region='Component'}
*
* In reactive forms, you'll also want to add your form directive (`formControlName` or
* `formControl`) on the main `<select>` tag. Like in the former example, you have the
* choice of binding to the `value` or `ngValue` property on the select's options.
*
* {@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}
*
* 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/
*
* * **npm package**: `@angular/forms`
*
* @stable
*/
@Directive({
@ -94,15 +122,11 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
}
/**
* Marks `<option>` as dynamic, so Angular can be notified when options change.
* @whatItDoes Marks `<option>` as dynamic, so Angular can be notified when options change.
*
* ### Example
* @howToUse
*
* ```
* <select name="city" ngModel>
* <option *ngFor="let c of cities" [value]="c"></option>
* </select>
* ```
* See docs for {@link SelectControlValueAccessor} for usage examples.
*
* @stable
*/