Skip to content

Commit cf377fe

Browse files
committed
fix(select): disabled state out of sync when swapping form group with a disabled one
Fixes the disabled state of a `mat-select` falling out of sync with its form control if the control's group is swapped out with one that is disabled on init. Fixes #17860.
1 parent f0c7a25 commit cf377fe

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/material/select/select.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
NG_VALUE_ACCESSOR,
5151
ReactiveFormsModule,
5252
Validators,
53+
FormBuilder,
5354
} from '@angular/forms';
5455
import {
5556
ErrorStateMatcher,
@@ -131,6 +132,7 @@ describe('MatSelect', () => {
131132
SelectWithGroupsAndNgContainer,
132133
SelectWithFormFieldLabel,
133134
SelectWithChangeEvent,
135+
SelectInsideDynamicFormGroup,
134136
]);
135137
}));
136138

@@ -1912,6 +1914,20 @@ describe('MatSelect', () => {
19121914
expect(fixture.componentInstance.select.panelOpen)
19131915
.toBe(true, `Expected select panelOpen property to become true.`);
19141916
}));
1917+
1918+
it('should keep the disabled state in sync if the form group is swapped and ' +
1919+
'disabled at the same time', fakeAsync(() => {
1920+
const fixture = TestBed.createComponent(SelectInsideDynamicFormGroup);
1921+
const instance = fixture.componentInstance;
1922+
fixture.detectChanges();
1923+
1924+
expect(instance.select.disabled).toBe(false);
1925+
1926+
instance.assignGroup(true);
1927+
fixture.detectChanges();
1928+
1929+
expect(instance.select.disabled).toBe(true);
1930+
}));
19151931
});
19161932

19171933
describe('animations', () => {
@@ -5430,3 +5446,30 @@ class SelectWithResetOptionAndFormControl {
54305446
@ViewChildren(MatOption) options: QueryList<MatOption>;
54315447
control = new FormControl();
54325448
}
5449+
5450+
5451+
@Component({
5452+
template: `
5453+
<form [formGroup]="form">
5454+
<mat-form-field>
5455+
<mat-select formControlName="control">
5456+
<mat-option value="1">One</mat-option>
5457+
</mat-select>
5458+
</mat-form-field>
5459+
</form>
5460+
`
5461+
})
5462+
class SelectInsideDynamicFormGroup {
5463+
@ViewChild(MatSelect) select: MatSelect;
5464+
form: FormGroup;
5465+
5466+
constructor(private _formBuilder: FormBuilder) {
5467+
this.assignGroup(false);
5468+
}
5469+
5470+
assignGroup(isDisabled: boolean) {
5471+
this.form = this._formBuilder.group({
5472+
control: {value: '', disabled: isDisabled}
5473+
});
5474+
}
5475+
}

src/material/select/select.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,11 @@ export class MatSelect extends _MatSelectMixinBase implements AfterContentInit,
605605

606606
ngDoCheck() {
607607
if (this.ngControl) {
608+
// The disabled state might go out of sync if the form group is swapped out. See #17860.
609+
if (this.ngControl.disabled !== this.disabled) {
610+
this.disabled = !!this.ngControl.disabled;
611+
}
612+
608613
this.updateErrorState();
609614
}
610615
}

0 commit comments

Comments
 (0)