feat(form-field): support native select element (#12707)

This commit is contained in:
vivian-hu
2018-08-30 07:02:48 -07:00
committed by Jeremy Elbourn
parent 53b4af6d2a
commit 4e419855ad
19 changed files with 510 additions and 29 deletions
+2 -2
View File
@@ -4,7 +4,7 @@
<form>
<mat-form-field class="demo-full-width">
<mat-label>Company (disabled)</mat-label>
<input matInput disabled value="Google">
<input matNativeControl disabled value="Google">
</mat-form-field>
<table style="width: 100%" cellspacing="0"><tr>
@@ -28,7 +28,7 @@
</mat-form-field>
<mat-form-field class="demo-full-width">
<mat-label>Address 2</mat-label>
<textarea matInput></textarea>
<textarea matNativeControl></textarea>
</mat-form-field>
</p>
<table style="width: 100%" cellspacing="0"><tr>
+161
View File
@@ -1,3 +1,163 @@
<mat-card class="demo-card demo-basic">
<mat-toolbar color="primary">Native Select</mat-toolbar>
<mat-card-content>
<form>
<h4>Basic</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car</mat-label>
<select matNativeControl id="mySelectId">
<option value="" disabled selected></option>
<option value="volvo">Volvo</option>
<option value="saab" disabled>Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Disabled and required</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car (disabled)</mat-label>
<select matNativeControl disabled required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Floating label</h4>
<mat-form-field>
<mat-label>Float with value</mat-label>
<select matNativeControl>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field>
<mat-label>Not float when empty</mat-label>
<select matNativeControl>
<option value="" selected></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field>
<mat-label>Float with no value, but with label</mat-label>
<select matNativeControl>
<option value="" selected label="--select one--"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field>
<mat-label>Float with no value, but with html</mat-label>
<select matNativeControl>
<option value="" selected>--select one--</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Looks</h4>
<mat-form-field appearance="legacy">
<mat-label>Legacy</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field appearance="standard">
<mat-label>Standard</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Fill</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label>Outline</mat-label>
<select matNativeControl>
<option value="volvo">volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Option group</h4>
<mat-form-field>
<select matNativeControl>
<optgroup label="Swedish Cars">
<option value="volvo">volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</optgroup>
</select>
</mat-form-field>
<h4>Place holder</h4>
<mat-form-field class="demo-full-width">
<select matNativeControl placeholder="place holder">
<option value="" disabled selected></option>
<option value="volvo">Volvo</option>
<option value="saab" disabled>Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<h4>Error message, hint, form sumbit</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car (required)</mat-label>
<select matNativeControl required [formControl]="selectFormControl">
<option label="--select something --"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<mat-error *ngIf="selectFormControl.hasError('required')">
This field is required
</mat-error>
<mat-hint>You can pick up your favorite car here</mat-hint>
</mat-form-field>
<h4>Error message with errorStateMatcher</h4>
<mat-form-field class="demo-full-width">
<mat-label>Select your car</mat-label>
<select matNativeControl required [formControl]="selectFormControl" [errorStateMatcher]="matcher">
<option label="--select something --"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<mat-error *ngIf="selectFormControl.hasError('required')">
This field is required
</mat-error>
<mat-hint>You can pick up your favorite car here</mat-hint>
</mat-form-field>
<button color="primary" mat-raised-button>Submit</button>
</form>
</mat-card-content>
</mat-card>
<mat-toolbar color="primary">mat-select</mat-toolbar>
Space above cards: <input type="number" [formControl]="topHeightCtrl">
<button mat-button (click)="showSelect=!showSelect">SHOW SELECT</button>
<div [style.height.px]="topHeightCtrl.value"></div>
@@ -240,3 +400,4 @@ Space above cards: <input type="number" [formControl]="topHeightCtrl">
</div>
<div style="height: 500px">This div is for testing scrolled selects.</div>
+14 -2
View File
@@ -7,9 +7,18 @@
*/
import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';
import {MatSelectChange} from '@angular/material';
import {FormControl, Validators} from '@angular/forms';
import {ErrorStateMatcher, MatSelectChange} from '@angular/material';
/** Error any time control is invalid */
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null): boolean {
if (control) {
return control.invalid;
}
return false;
}
}
@Component({
moduleId: module.id,
@@ -37,6 +46,7 @@ export class SelectDemo {
drinksTheme = 'primary';
pokemonTheme = 'primary';
compareByValue = true;
selectFormControl = new FormControl('', Validators.required);
foods = [
{value: null, viewValue: 'None'},
@@ -137,6 +147,8 @@ export class SelectDemo {
return o1 === o2;
}
matcher = new MyErrorStateMatcher();
toggleSelected() {
this.currentAppearanceValue = this.currentAppearanceValue ? null : this.digimon[0].value;
}
+4 -2
View File
@@ -7,7 +7,8 @@ In this document, "form field" refers to the wrapper component `<mat-form-field>
(e.g. the input, textarea, select, etc.)
The following Angular Material components are designed to work inside a `<mat-form-field>`:
* [`<input matInput>` &amp; `<textarea matInput>`](https://material.angular.io/components/input/overview)
* [`<input matNativeControl>` &amp; `<textarea matNativeControl>`](https://material.angular.io/components/input/overview)
* [`<select matNativeControl>`](https://material.angular.io/components/select/overview)
* [`<mat-select>`](https://material.angular.io/components/select/overview)
* [`<mat-chip-list>`](https://material.angular.io/components/chips/overview)
@@ -41,7 +42,8 @@ want a floating label, add a `<mat-label>` to the `mat-form-field`.
### Floating label
The floating label is a text label displayed on top of the form field control when
the control does not contain any text. By default, when text is present the floating label
the control does not contain any text or when `<select matNativeControl>` does not show any option text.
By default, when text is present the floating label
floats above the form field control. The label for a form field can be specified by adding a
`mat-label` element.
+26
View File
@@ -121,3 +121,29 @@ textarea.mat-input-element {
padding: 2px 0;
margin: -2px 0;
}
// Encoded material design select arrow svg
/* stylelint-disable max-line-length */
$mat-native-select-arrow-svg: 'data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%2210%22%20height%3D%225%22%20viewBox%3D%227%2010%2010%205%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%230%22%20fill-rule%3D%22evenodd%22%20opacity%3D%22.54%22%20d%3D%22M7%2010l5%205%205-5z%22%2F%3E%3C%2Fsvg%3E';
/* stylelint-enable */
// Remove the native select down arrow and replace it with material design arrow
select.mat-input-element {
&::-ms-expand {
display: none;
}
-moz-appearance: none;
-webkit-appearance: none;
position: relative;
background-color: transparent;
background-image: url($mat-native-select-arrow-svg);
background-repeat: no-repeat;
display: inline-flex;
box-sizing: border-box;
background-position: right center;
[dir='rtl'] & {
background-position: left center;
}
}
+135 -2
View File
@@ -443,6 +443,26 @@ describe('MatInput without forms', () => {
expect(inputEl.disabled).toBe(true);
}));
it('supports the disabled attribute as binding for select', fakeAsync(() => {
const fixture = createComponent(MatInputSelect);
fixture.detectChanges();
const formFieldEl =
fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
const selectEl = fixture.debugElement.query(By.css('select')).nativeElement;
expect(formFieldEl.classList.contains('mat-form-field-disabled'))
.toBe(false, `Expected form field not to start out disabled.`);
expect(selectEl.disabled).toBe(false);
fixture.componentInstance.disabled = true;
fixture.detectChanges();
expect(formFieldEl.classList.contains('mat-form-field-disabled'))
.toBe(true, `Expected form field to look disabled after property is set.`);
expect(selectEl.disabled).toBe(true);
}));
it('supports the required attribute as binding', fakeAsync(() => {
let fixture = createComponent(MatInputWithRequired);
fixture.detectChanges();
@@ -457,6 +477,20 @@ describe('MatInput without forms', () => {
expect(inputEl.required).toBe(true);
}));
it('supports the required attribute as binding for select', fakeAsync(() => {
const fixture = createComponent(MatInputSelect);
fixture.detectChanges();
const selectEl = fixture.debugElement.query(By.css('select')).nativeElement;
expect(selectEl.required).toBe(false);
fixture.componentInstance.required = true;
fixture.detectChanges();
expect(selectEl.required).toBe(true);
}));
it('supports the type attribute as binding', fakeAsync(() => {
let fixture = createComponent(MatInputWithType);
fixture.detectChanges();
@@ -479,6 +513,14 @@ describe('MatInput without forms', () => {
expect(textarea).not.toBeNull();
}));
it('supports select', fakeAsync(() => {
const fixture = createComponent(MatInputSelect);
fixture.detectChanges();
const nativeSelect: HTMLTextAreaElement = fixture.nativeElement.querySelector('select');
expect(nativeSelect).not.toBeNull();
}));
it('sets the aria-describedby when a hintLabel is set', fakeAsync(() => {
let fixture = createComponent(MatInputHintLabelTestController);
@@ -577,6 +619,41 @@ describe('MatInput without forms', () => {
expect(formFieldEl.classList).toContain('mat-form-field-should-float');
}));
it('should float labels when select has value', fakeAsync(() => {
const fixture = createComponent(MatInputSelect);
fixture.detectChanges();
const formFieldEl = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
expect(formFieldEl.classList).toContain('mat-form-field-should-float');
}));
it('should not float labels when select has no value, no option label, ' +
'no option innerHtml', fakeAsync(() => {
const fixture = createComponent(MatInputSelectWithNoLabelNoValue);
fixture.detectChanges();
const formFieldEl = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
expect(formFieldEl.classList).not.toContain('mat-form-field-should-float');
}));
it('should floating labels when select has no value but has option label',
fakeAsync(() => {
const fixture = createComponent(MatInputSelectWithLabel);
fixture.detectChanges();
const formFieldEl = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement;
expect(formFieldEl.classList).toContain('mat-form-field-should-float');
}));
it('should floating labels when select has no value but has option innerHTML',
fakeAsync(() => {
const fixture = createComponent(MatInputSelectWithInnerHtml);
fixture.detectChanges();
const formFieldEl = fixture.debugElement.query(By.css('.mat-form-field'))
.nativeElement;
expect(formFieldEl.classList).toContain('mat-form-field-should-float');
}));
it('should never float the label when floatLabel is set to false', fakeAsync(() => {
let fixture = createComponent(MatInputWithDynamicLabel);
@@ -1296,7 +1373,7 @@ function createComponent<T>(component: Type<T>,
@Component({
template: `
<mat-form-field>
<input matInput id="test-id" placeholder="test">
<input matNativeControl id="test-id" placeholder="test">
</mat-form-field>`
})
class MatInputWithId {}
@@ -1503,7 +1580,8 @@ class MatInputWithDynamicLabel {
@Component({
template: `
<mat-form-field>
<textarea matInput [rows]="rows" [cols]="cols" [wrap]="wrap" placeholder="Snacks"></textarea>
<textarea matNativeControl [rows]="rows" [cols]="cols" [wrap]="wrap" placeholder="Snacks">
</textarea>
</mat-form-field>`
})
class MatInputTextareaWithBindings {
@@ -1726,3 +1804,58 @@ class AutosizeTextareaInATab {}
`
})
class AutosizeTextareaInAStep {}
@Component({
template: `
<mat-form-field>
<select matNativeControl id="test-id" [disabled]="disabled" [required]="required">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>`
})
class MatInputSelect {
disabled: boolean;
required: boolean;
}
@Component({
template: `
<mat-form-field>
<select matNativeControl>
<option value="" disabled selected></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>`
})
class MatInputSelectWithNoLabelNoValue {}
@Component({
template: `
<mat-form-field>
<select matNativeControl>
<option value="" label="select a car"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>`
})
class MatInputSelectWithLabel {}
@Component({
template: `
<mat-form-field>
<select matNativeControl>
<option value="">select a car</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>`
})
class MatInputSelectWithInnerHtml {}
+19 -3
View File
@@ -64,7 +64,8 @@ export const _MatInputMixinBase: CanUpdateErrorStateCtor & typeof MatInputBase =
/** Directive that allows a native input to work inside a `MatFormField`. */
@Directive({
selector: `input[matInput], textarea[matInput]`,
selector: `input[matInput], textarea[matInput], select[matNativeControl],
input[matNativeControl], textarea[matNativeControl]`,
exportAs: 'matInput',
host: {
/**
@@ -78,7 +79,7 @@ export const _MatInputMixinBase: CanUpdateErrorStateCtor & typeof MatInputBase =
'[attr.placeholder]': 'placeholder',
'[disabled]': 'disabled',
'[required]': 'required',
'[readonly]': 'readonly',
'[attr.readonly]': 'readonly && !_isNativeSelect || null',
'[attr.aria-describedby]': '_ariaDescribedby || null',
'[attr.aria-invalid]': 'errorState',
'[attr.aria-required]': 'required.toString()',
@@ -99,6 +100,9 @@ export class MatInput extends _MatInputMixinBase implements MatFormFieldControl<
/** Whether the component is being rendered on the server. */
_isServer = false;
/** Whether the component is a native html select. */
_isNativeSelect = false;
/**
* Implemented as part of MatFormFieldControl.
* @docs-private
@@ -257,6 +261,7 @@ export class MatInput extends _MatInputMixinBase implements MatFormFieldControl<
}
this._isServer = !this._platform.isBrowser;
this._isNativeSelect = this._elementRef.nativeElement.nodeName.toLowerCase() === 'select';
}
ngOnInit() {
@@ -362,7 +367,18 @@ export class MatInput extends _MatInputMixinBase implements MatFormFieldControl<
* Implemented as part of MatFormFieldControl.
* @docs-private
*/
get shouldLabelFloat(): boolean { return this.focused || !this.empty; }
get shouldLabelFloat(): boolean {
if (this._isNativeSelect) {
// For a single-selection `<select>`, the label should float when the selected option has
// a non-empty display value. For a `<select multiple>`, the label *always* floats to avoid
// overlapping the label with the options.
const selectElement = this._elementRef.nativeElement;
return selectElement.multiple || !this.empty || selectElement.options[0].label ||
this.focused;
} else {
return this.focused || !this.empty;
}
}
/**
* Implemented as part of MatFormFieldControl.
+21 -7
View File
@@ -8,6 +8,14 @@ To add options to the select, add `<mat-option>` elements to the `<mat-select>`.
has a `value` property that can be used to set the value that will be selected if the user chooses
this option. The content of the `<mat-option>` is what will be shown to the user.
Angular Material also supports use of the native `<select>` element inside of
`<mat-form-field>`. The native control has several performance, accessibility,
and usability advantages. See [the documentation for
form-field](https://material.angular.io/components/form-field) for more information.
To use a native select inside `<mat-form-field>`, add the `matNativeControl` attribute
to the `<select>` element.
<!-- example(select-overview) -->
### Getting and setting the select value
@@ -17,7 +25,7 @@ forms.
<!-- example(select-value-binding) -->
The `<mat-select>` also supports all of the form directives from the core `FormsModule` (`NgModel`) and
Both`<mat-select>` and `<select>` support all of the form directives from the core `FormsModule` (`NgModel`) and
`ReactiveFormsModule` (`FormControl`, `FormGroup`, etc.) As with native `<select>`, `<mat-select>`
also supports a `compareWith` function. (Additional information about using a custom `compareWith`
function can be found in the
@@ -27,7 +35,7 @@ function can be found in the
### Form field features
There are a number of `<mat-form-field>` features that can be used with any `<mat-select>`. These
There are a number of `<mat-form-field>` features that can be used with both `<select>` and `<mat-select>`. These
include error messages, hint text, prefix & suffix, and theming. For additional information about
these features, see the
[form field documentation](https://material.angular.io/components/form-field/overview).
@@ -45,7 +53,7 @@ In some cases that `<mat-form-field>` may use the placeholder as the label (see
### Disabling the select or individual options
It is possible to disable the entire select or individual options in the select by using the
disabled property on the `<mat-select>` and the `<mat-option>` components respectively.
disabled property on the `<select>` or `<mat-select>` and the `<option>` or <mat-option>` elements respectively.
<!-- example(select-disabled) -->
@@ -71,11 +79,15 @@ by setting the `multiple` property. This will allow the user to select multiple
using the `<mat-select>` in multiple selection mode, its value will be a sorted list of all selected
values rather than a single value.
Using multiple selection with a native select element (`<select multiple>`) is discouraged
inside `<mat-form-field>`, as the inline listbox appearance is inconsistent with other
Material Design components.
<!-- example(select-multiple) -->
### Customizing the trigger label
If you want to display a custom trigger label inside a select, you can use the
If you want to display a custom trigger label inside a `<mat-select>`, you can use the
`<mat-select-trigger>` element.
<!-- example(select-custom-trigger) -->
@@ -98,7 +110,7 @@ which can be used to apply additional CSS classes to the dropdown panel.
The `<mat-form-field>` allows you to
[associate error messages](https://material.angular.io/components/form-field/overview#error-messages)
with your `<mat-select>`. By default, these error messages are shown when the control is invalid and
with your `<select>` or `<mat-select>`. By default, these error messages are shown when the control is invalid and
either the user has interacted with (touched) the element or the parent form has been submitted. If
you wish to override this behavior (e.g. to show the error as soon as the invalid control is dirty
or when a parent form group is invalid), you can use the `errorStateMatcher` property of the
@@ -130,10 +142,12 @@ globally cause input errors to show when the input is dirty and invalid.
### Accessibility
The select component without text or label should be given a meaningful label via
The `<mat-select>` component without text or label should be given a meaningful label via
`aria-label` or `aria-labelledby`.
The select component has `role="listbox"` and options inside select have `role="option"`.
The `<mat-select>` component has `role="listbox"` and options inside select have `role="option"`.
The native `<select>` offers the best accessibility because it is supported directly by screen-readers.
### Troubleshooting
@@ -1,12 +1,24 @@
<p>
<mat-checkbox [formControl]="disableSelect">Disable select</mat-checkbox>
</p>
<p>
<mat-form-field>
<mat-select placeholder="Choose an option" [disabled]="disableSelect.value">
<mat-option value="option1">Option 1</mat-option>
<mat-option value="option2" disabled>Option 2 (disabled)</mat-option>
<mat-option value="option3">Option 3</mat-option>
</mat-select>
</mat-form-field>
</p>
<h4>mat-select</h4>
<mat-form-field>
<mat-select placeholder="Choose an option" [disabled]="disableSelect.value">
<mat-option value="option1">Option 1</mat-option>
<mat-option value="option2" disabled>Option 2 (disabled)</mat-option>
<mat-option value="option3">Option 3</mat-option>
</mat-select>
</mat-form-field>
<h4>native html select</h4>
<mat-form-field>
<select matNativeControl placeholder="Choose an option" [disabled]="disableSelect.value">
<option value="" disabled selected></option>
<option value="volvo">Volvo</option>
<option value="saab" disabled>Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
@@ -1,3 +1,4 @@
<h4>mat-select</h4>
<mat-form-field>
<mat-select placeholder="Choose one" [formControl]="selected" [errorStateMatcher]="matcher">
<mat-option>Clear</mat-option>
@@ -10,3 +11,16 @@
Your selection is invalid
</mat-error>
</mat-form-field>
<h4>native html select</h4>
<mat-form-field class="demo-full-width">
<select matNativeControl placeholder="Choose one" [formControl]="nativeSelectFormControl" [errorStateMatcher]="matcher">
<option value=""></option>
<option value="valid" selected>Valid option</option>
<option value="invalid">Invalid option</option>
</select>
<mat-error *ngIf="nativeSelectFormControl.hasError('required')">You must make a selection</mat-error>
<mat-error *ngIf="nativeSelectFormControl.hasError('pattern') && !nativeSelectFormControl.hasError('required')">
Your selection is invalid
</mat-error>
</mat-form-field>
@@ -22,5 +22,15 @@ export class SelectErrorStateMatcherExample {
Validators.pattern('valid'),
]);
selectFormControl = new FormControl('valid', [
Validators.required,
Validators.pattern('valid'),
]);
nativeSelectFormControl = new FormControl('valid', [
Validators.required,
Validators.pattern('valid'),
]);
matcher = new MyErrorStateMatcher();
}
@@ -1,4 +1,5 @@
<form>
<h4>mat-select</h4>
<mat-form-field>
<mat-select placeholder="Favorite food" [(ngModel)]="selectedValue" name="food">
<mat-option *ngFor="let food of foods" [value]="food.value">
@@ -6,6 +7,15 @@
</mat-option>
</mat-select>
</mat-form-field>
<p> Selected value: {{selectedValue}} </p>
<p> Selected food: {{selectedValue}} </p>
<h4>native html select</h4>
<mat-form-field>
<select matNativeControl placeholder="Favorite car" [(ngModel)]="selectedCar" name="car">
<option value="" disabled selected></option>
<option *ngFor="let car of cars" [value]="car.value">
{{car.viewValue}}
</option>
</select>
</mat-form-field>
<p> Selected car: {{selectedCar}} </p>
</form>
@@ -5,6 +5,11 @@ export interface Food {
viewValue: string;
}
export interface Car {
value: string;
viewValue: string;
}
/**
* @title Select in a form
*/
@@ -15,10 +20,17 @@ export interface Food {
})
export class SelectFormExample {
selectedValue: string;
selectedCar: string;
foods: Food[] = [
{value: 'steak-0', viewValue: 'Steak'},
{value: 'pizza-1', viewValue: 'Pizza'},
{value: 'tacos-2', viewValue: 'Tacos'}
];
cars: Car[] = [
{value: 'volvo', viewValue: 'Volvo'},
{value: 'saab', viewValue: 'Saab'},
{value: 'mercedes', viewValue: 'Mercedes'}
];
}
@@ -1,3 +1,4 @@
<h4>mat select</h4>
<mat-form-field>
<mat-select placeholder="Favorite animal" [formControl]="animalControl" required>
<mat-option>--</mat-option>
@@ -8,3 +9,19 @@
<mat-error *ngIf="animalControl.hasError('required')">Please choose an animal</mat-error>
<mat-hint>{{animalControl.value?.sound}}</mat-hint>
</mat-form-field>
<h4>native html select</h4>
<mat-form-field>
<mat-label>Select your car (required)</mat-label>
<select matNativeControl required [formControl]="selectFormControl">
<option label="--select something --"></option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<mat-error *ngIf="selectFormControl.hasError('required')">
This field is required
</mat-error>
<mat-hint>You can pick up your favorite car here</mat-hint>
</mat-form-field>
@@ -14,6 +14,7 @@ export interface Animal {
})
export class SelectHintErrorExample {
animalControl = new FormControl('', [Validators.required]);
selectFormControl = new FormControl('', Validators.required);
animals: Animal[] = [
{name: 'Dog', sound: 'Woof!'},
{name: 'Cat', sound: 'Meow!'},
@@ -1,3 +1,4 @@
<h4>mat-select</h4>
<mat-form-field>
<mat-select placeholder="Pokemon" [formControl]="pokemonControl">
<mat-option>-- None --</mat-option>
@@ -9,3 +10,17 @@
</mat-optgroup>
</mat-select>
</mat-form-field>
<h4>native html select</h4>
<mat-form-field>
<select matNativeControl>
<optgroup label="Swedish Cars">
<option value="volvo">volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</optgroup>
</select>
</mat-form-field>
@@ -1,3 +1,4 @@
<h4>Basic mat-select</h4>
<mat-form-field>
<mat-select placeholder="Favorite food">
<mat-option *ngFor="let food of foods" [value]="food.value">
@@ -5,3 +6,13 @@
</mat-option>
</mat-select>
</mat-form-field>
<h4>Basic native select</h4>
<mat-form-field>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
@@ -1,6 +1,19 @@
<h4>mat-select</h4>
<mat-form-field>
<mat-select placeholder="State">
<mat-option>None</mat-option>
<mat-option *ngFor="let state of states" [value]="state">{{state}}</mat-option>
</mat-select>
</mat-form-field>
<h4>native html select</h4>
<mat-form-field>
<mat-label>Select your car</mat-label>
<select matNativeControl id="mySelectId">
<option value="" disabled selected></option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>