Skip to content

Commit

Permalink
fix(material/form-field): not visually disabled if form control is di…
Browse files Browse the repository at this point in the history
…sabled without emitting an event (#26088)

Fixes that the form field wasn't visually disabled if the consumer disables it using `emitEvents: false`.

Fixes #26057.
  • Loading branch information
crisbeto authored Nov 28, 2022
1 parent 3c03ad4 commit 547357a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
16 changes: 14 additions & 2 deletions src/material/input/input.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ describe('MatMdcInput with forms', () => {

describe('custom error behavior', () => {
it('should display an error message when a custom error matcher returns true', fakeAsync(() => {
let fixture = createComponent(MatInputWithCustomErrorStateMatcher);
let fixture = createComponent(InputInFormGroup);
fixture.detectChanges();

let component = fixture.componentInstance;
Expand Down Expand Up @@ -1356,6 +1356,18 @@ describe('MatMdcInput with forms', () => {

expect(notch.style.width).toBeTruthy();
}));

it('should mark the form field as disabled when a group is disabled with emitEvent: false', fakeAsync(() => {
const fixture = createComponent(InputInFormGroup);
fixture.detectChanges();

const mdcTextField = fixture.nativeElement.querySelector('.mdc-text-field');
expect(mdcTextField.classList).not.toContain('mdc-text-field--disabled');

fixture.componentInstance.formGroup.disable({emitEvent: false});
fixture.detectChanges();
expect(mdcTextField.classList).toContain('mdc-text-field--disabled');
}));
});

describe('MatFormField default options', () => {
Expand Down Expand Up @@ -1793,7 +1805,7 @@ class MatInputWithFormErrorMessages {
</form>
`,
})
class MatInputWithCustomErrorStateMatcher {
class InputInFormGroup {
formGroup = new FormGroup({
name: new FormControl('', [Validators.required, Validators.pattern(/valid value/)]),
});
Expand Down
12 changes: 9 additions & 3 deletions src/material/input/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,6 @@ export class MatInput
*/
@Input()
get disabled(): boolean {
if (this.ngControl && this.ngControl.disabled !== null) {
return this.ngControl.disabled;
}
return this._disabled;
}
set disabled(value: BooleanInput) {
Expand Down Expand Up @@ -356,6 +353,15 @@ export class MatInput
// error triggers that we can't subscribe to (e.g. parent form submissions). This means
// that whatever logic is in here has to be super lean or we risk destroying the performance.
this.updateErrorState();

// Since the input isn't a `ControlValueAccessor`, we don't have a good way of knowing when
// the disabled state has changed. We can't use the `ngControl.statusChanges`, because it
// won't fire if the input is disabled with `emitEvents = false`, despite the input becoming
// disabled.
if (this.ngControl.disabled !== null && this.ngControl.disabled !== this.disabled) {
this.disabled = this.ngControl.disabled;
this.stateChanges.next();
}
}

// We need to dirty-check the native element's value, because there are some cases where
Expand Down

0 comments on commit 547357a

Please sign in to comment.