docs(forms): add select control examples (#11728)
This commit is contained in:
parent
0621f07a2c
commit
bf81b06a28
|
@ -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" } }');
|
||||
});
|
||||
|
||||
});
|
|
@ -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 {
|
||||
}
|
|
@ -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
|
|
@ -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" } }');
|
||||
});
|
||||
|
||||
});
|
|
@ -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 {
|
||||
}
|
|
@ -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
|
|
@ -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`
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue