Skip to content

fix(button-toggle): static checked value not being picked up #18442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/material/button-toggle/button-toggle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ describe('MatButtonToggle without forms', () => {
RepeatedButtonTogglesWithPreselectedValue,
ButtonToggleWithTabindex,
ButtonToggleWithStaticName,
ButtonToggleWithStaticChecked,
],
});

Expand Down Expand Up @@ -888,6 +889,14 @@ describe('MatButtonToggle without forms', () => {
.toBe(true);
});

it('should be able to pre-check a button toggle using a static checked binding', () => {
const fixture = TestBed.createComponent(ButtonToggleWithStaticChecked);
fixture.detectChanges();

expect(fixture.componentInstance.toggles.map(t => t.checked)).toEqual([false, true]);
expect(fixture.componentInstance.group.value).toBe('2');
});

});

@Component({
Expand Down Expand Up @@ -1050,3 +1059,17 @@ class ButtonToggleWithTabindex {}
template: `<mat-button-toggle name="custom-name"></mat-button-toggle>`
})
class ButtonToggleWithStaticName {}


@Component({
template: `
<mat-button-toggle-group>
<mat-button-toggle value="1">One</mat-button-toggle>
<mat-button-toggle value="2" checked>Two</mat-button-toggle>
</mat-button-toggle-group>
`
})
class ButtonToggleWithStaticChecked {
@ViewChild(MatButtonToggleGroup) group: MatButtonToggleGroup;
@ViewChildren(MatButtonToggle) toggles: QueryList<MatButtonToggle>;
}
19 changes: 14 additions & 5 deletions src/material/button-toggle/button-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export class MatButtonToggleGroup implements ControlValueAccessor, OnInit, After
// the side-effect is that we may end up updating the model value out of sequence in others
// The `deferEvents` flag allows us to decide whether to do it on a case-by-case basis.
if (deferEvents) {
Promise.resolve(() => this._updateModelValue(isUserInput));
Promise.resolve().then(() => this._updateModelValue(isUserInput));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change has nothing to do with the fix, but I noticed that it wasn't actually doing anything so I fixed it.

} else {
this._updateModelValue(isUserInput);
}
Expand Down Expand Up @@ -502,16 +502,25 @@ export class MatButtonToggle extends _MatButtonToggleMixinBase implements OnInit
}

ngOnInit() {
this._isSingleSelector = this.buttonToggleGroup && !this.buttonToggleGroup.multiple;
const group = this.buttonToggleGroup;
this._isSingleSelector = group && !group.multiple;
this._type = this._isSingleSelector ? 'radio' : 'checkbox';
this.id = this.id || `mat-button-toggle-${_uniqueIdCounter++}`;

if (this._isSingleSelector) {
this.name = this.buttonToggleGroup.name;
this.name = group.name;
}

if (this.buttonToggleGroup && this.buttonToggleGroup._isPrechecked(this)) {
this.checked = true;
if (group) {
if (group._isPrechecked(this)) {
this.checked = true;
} else if (group._isSelected(this) !== this._checked) {
// As as side effect of the circular dependency between the toggle group and the button,
// we may end up in a state where the button is supposed to be checked on init, but it
// isn't, because the checked value was assigned too early. This can happen when Ivy
// assigns the static input value before the `ngOnInit` has run.
group._syncButtonToggle(this, this._checked);
}
}

this._focusMonitor.monitor(this._elementRef, true);
Expand Down