Skip to content

Commit 83954c5

Browse files
committed
Use FormControl and only one of incompatible form options
1 parent ab870d1 commit 83954c5

File tree

5 files changed

+34
-28
lines changed

5 files changed

+34
-28
lines changed

src/demo-app/input/input-demo.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Component} from '@angular/core';
2-
import {FormControl, Validators, NgControl} from '@angular/forms';
2+
import {FormControl, Validators} from '@angular/forms';
33

44

55
let max = 5;
@@ -45,7 +45,7 @@ export class InputDemo {
4545
}
4646
}
4747

48-
customErrorStateMatcher(c: NgControl): boolean {
48+
customErrorStateMatcher(c: FormControl): boolean {
4949
const hasInteraction = c.dirty || c.touched;
5050
const isInvalid = c.invalid;
5151

src/lib/core/error/error-options.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,31 @@
77
*/
88

99
import {InjectionToken} from '@angular/core';
10-
import {NgControl, FormGroupDirective, NgForm} from '@angular/forms';
10+
import {FormControl, FormGroupDirective, Form, NgForm} from '@angular/forms';
1111

1212
/** Injection token that can be used to specify the global error options. */
1313
export const MD_ERROR_GLOBAL_OPTIONS = new InjectionToken<ErrorOptions>('md-error-global-options');
1414

1515
export type ErrorStateMatcher =
16-
(control: NgControl, parentFormGroup: FormGroupDirective, parentForm: NgForm) => boolean;
16+
(control: FormControl, form: FormGroupDirective | NgForm) => boolean;
1717

1818
export interface ErrorOptions {
1919
errorStateMatcher?: ErrorStateMatcher;
2020
}
2121

22-
export function defaultErrorStateMatcher(control: NgControl, formGroup: FormGroupDirective,
23-
form: NgForm): boolean {
24-
25-
const isInvalid = control && control.invalid;
26-
const isTouched = control && control.touched;
27-
const isSubmitted = (formGroup && formGroup.submitted) ||
28-
(form && form.submitted);
22+
export function defaultErrorStateMatcher(control: FormControl, form: FormGroupDirective | NgForm) {
23+
const isInvalid = control.invalid;
24+
const isTouched = control.touched;
25+
const isSubmitted = form && form.submitted;
2926

3027
return !!(isInvalid && (isTouched || isSubmitted));
3128
}
3229

33-
export function showOnDirtyErrorStateMatcher(control: NgControl, formGroup: FormGroupDirective,
34-
form: NgForm): boolean {
35-
36-
const isInvalid = control && control.invalid;
37-
const isDirty = control && control.dirty;
38-
const isSubmitted = (formGroup && formGroup.submitted) ||
39-
(form && form.submitted);
30+
export function showOnDirtyErrorStateMatcher(control: FormControl,
31+
form: FormGroupDirective | NgForm) {
32+
const isInvalid = control.invalid;
33+
const isDirty = control.dirty;
34+
const isSubmitted = form && form.submitted;
4035

4136
return !!(isInvalid && (isDirty || isSubmitted));
4237
}

src/lib/input/input-container.spec.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -760,10 +760,12 @@ describe('MdInputContainer', function () {
760760
let component = fixture.componentInstance;
761761
let containerEl = fixture.debugElement.query(By.css('md-input-container')).nativeElement;
762762

763-
expect(component.formControl.invalid).toBe(true, 'Expected form control to be invalid');
763+
const control = component.formGroup.get('name')!;
764+
765+
expect(control.invalid).toBe(true, 'Expected form control to be invalid');
764766
expect(containerEl.querySelectorAll('md-error').length).toBe(0, 'Expected no error messages');
765767

766-
component.formControl.markAsTouched();
768+
control.markAsTouched();
767769
fixture.detectChanges();
768770

769771
fixture.whenStable().then(() => {
@@ -1136,10 +1138,10 @@ class MdInputContainerWithFormErrorMessages {
11361138

11371139
@Component({
11381140
template: `
1139-
<form #form="ngForm" novalidate>
1141+
<form [formGroup]="formGroup">
11401142
<md-input-container>
11411143
<input mdInput
1142-
[formControl]="formControl"
1144+
formControlName="name"
11431145
[errorStateMatcher]="customErrorStateMatcher.bind(this)">
11441146
<md-hint>Please type something</md-hint>
11451147
<md-error>This field is required</md-error>
@@ -1148,8 +1150,10 @@ class MdInputContainerWithFormErrorMessages {
11481150
`
11491151
})
11501152
class MdInputContainerWithCustomErrorStateMatcher {
1151-
@ViewChild('form') form: NgForm;
1152-
formControl = new FormControl('', Validators.required);
1153+
formGroup = new FormGroup({
1154+
name: new FormControl('', Validators.required)
1155+
});
1156+
11531157
errorState = false;
11541158

11551159
customErrorStateMatcher(): boolean {

src/lib/input/input-container.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
} from '@angular/core';
3030
import {animate, state, style, transition, trigger} from '@angular/animations';
3131
import {coerceBooleanProperty, Platform} from '../core';
32-
import {FormGroupDirective, NgControl, NgForm} from '@angular/forms';
32+
import {FormGroupDirective, NgControl, NgForm, FormControl} from '@angular/forms';
3333
import {getSupportedInputTypes} from '../core/platform/features';
3434
import {
3535
getMdInputContainerDuplicatedHintError,
@@ -264,7 +264,8 @@ export class MdInputDirective {
264264
/** Whether the input is in an error state. */
265265
_isErrorState(): boolean {
266266
const control = this._ngControl;
267-
return this.errorStateMatcher(control, this._parentFormGroup, this._parentForm);
267+
const form = this._parentFormGroup || this._parentForm;
268+
return control && this.errorStateMatcher(control.control as FormControl, form);
268269
}
269270

270271
/** Make sure the input is a supported type. */

src/lib/input/input.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,14 @@ the error messages.
125125
```
126126

127127
```ts
128-
function myErrorStateMatcher(control: NgControl, parentFg: FormGroupDirective, parentForm: NgForm): boolean {
129-
return !!(control.invalid && control.dirty);
128+
function myErrorStateMatcher(control: FormControl, form: FormGroupDirective | NgForm): boolean {
129+
// Error when invalid control is dirty, touched, or submitted
130+
const isInvalid = control.invalid;
131+
const isDirty = control.dirty;
132+
const isTouched = control.touched;
133+
const isSubmitted = form && form.submitted;
134+
135+
return !!(isInvalid && (isDirty || isTouched || isSubmitted)));
130136
}
131137
```
132138

0 commit comments

Comments
 (0)