Skip to content

Commit bbc5f6a

Browse files
tinayuangaokara
authored andcommitted
fix(radio): fix radio group behavior on change (#1735)
1 parent b9fe75a commit bbc5f6a

File tree

2 files changed

+62
-26
lines changed

2 files changed

+62
-26
lines changed

src/lib/radio/radio.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,29 @@ describe('MdRadio', () => {
285285
expect(groupInstance.value).toBe('water');
286286
expect(changeSpy).not.toHaveBeenCalled();
287287
});
288+
289+
it(`should update checked status if changed value to radio group's value`, () => {
290+
let changeSpy = jasmine.createSpy('radio-group change listener');
291+
groupInstance.change.subscribe(changeSpy);
292+
groupInstance.value = 'apple';
293+
294+
expect(changeSpy).not.toHaveBeenCalled();
295+
expect(groupInstance.value).toBe('apple');
296+
expect(groupInstance.selected).toBeFalsy('expect group selected to be null');
297+
expect(radioInstances[0].checked).toBeFalsy('should not select the first button');
298+
expect(radioInstances[1].checked).toBeFalsy('should not select the second button');
299+
expect(radioInstances[2].checked).toBeFalsy('should not select the third button');
300+
301+
radioInstances[0].value = 'apple';
302+
303+
fixture.detectChanges();
304+
305+
expect(groupInstance.selected).toBe(
306+
radioInstances[0], 'expect group selected to be first button');
307+
expect(radioInstances[0].checked).toBeTruthy('expect group select the first button');
308+
expect(radioInstances[1].checked).toBeFalsy('should not select the second button');
309+
expect(radioInstances[2].checked).toBeFalsy('should not select the third button');
310+
});
288311
});
289312

290313
describe('group with ngModel', () => {

src/lib/radio/radio.ts

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
127127
this._value = newValue;
128128

129129
this._updateSelectedRadioFromValue();
130+
this._checkSelectedRadioButton();
131+
}
132+
}
133+
134+
_checkSelectedRadioButton() {
135+
if (this.selected && !this._selected.checked) {
136+
this._selected.checked = true;
130137
}
131138
}
132139

@@ -139,9 +146,7 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
139146
this._selected = selected;
140147
this.value = selected ? selected.value : null;
141148

142-
if (selected && !selected.checked) {
143-
selected.checked = true;
144-
}
149+
this._checkSelectedRadioButton();
145150
}
146151

147152
/**
@@ -180,14 +185,13 @@ export class MdRadioGroup implements AfterContentInit, ControlValueAccessor {
180185
let isAlreadySelected = this._selected != null && this._selected.value == this._value;
181186

182187
if (this._radios != null && !isAlreadySelected) {
183-
let matchingRadio = this._radios.filter(radio => radio.value == this._value)[0];
184-
185-
if (matchingRadio) {
186-
this.selected = matchingRadio;
187-
} else if (this.value == null) {
188-
this.selected = null;
189-
this._radios.forEach(radio => { radio.checked = false; });
190-
}
188+
this._selected = null;
189+
this._radios.forEach(radio => {
190+
radio.checked = this.value == radio.value;
191+
if (radio.checked) {
192+
this._selected = radio;
193+
}
194+
});
191195
}
192196
}
193197

@@ -303,19 +307,21 @@ export class MdRadioButton implements OnInit {
303307
}
304308

305309
set checked(newCheckedState: boolean) {
306-
this._checked = newCheckedState;
307-
308-
if (newCheckedState && this.radioGroup && this.radioGroup.value != this.value) {
309-
this.radioGroup.selected = this;
310-
} else if (!newCheckedState && this.radioGroup && this.radioGroup.value == this.value) {
311-
// When unchecking the selected radio button, update the selected radio
312-
// property on the group.
313-
this.radioGroup.selected = null;
314-
}
310+
if (this._checked != newCheckedState) {
311+
this._checked = newCheckedState;
312+
313+
if (newCheckedState && this.radioGroup && this.radioGroup.value != this.value) {
314+
this.radioGroup.selected = this;
315+
} else if (!newCheckedState && this.radioGroup && this.radioGroup.value == this.value) {
316+
// When unchecking the selected radio button, update the selected radio
317+
// property on the group.
318+
this.radioGroup.selected = null;
319+
}
315320

316-
if (newCheckedState) {
317-
// Notify all radio buttons with the same name to un-check.
318-
this.radioDispatcher.notify(this.id, this.name);
321+
if (newCheckedState) {
322+
// Notify all radio buttons with the same name to un-check.
323+
this.radioDispatcher.notify(this.id, this.name);
324+
}
319325
}
320326
}
321327

@@ -327,10 +333,17 @@ export class MdRadioButton implements OnInit {
327333

328334
set value(value: any) {
329335
if (this._value != value) {
330-
if (this.radioGroup != null && this.checked) {
331-
this.radioGroup.value = value;
332-
}
333336
this._value = value;
337+
if (this.radioGroup != null) {
338+
if (!this.checked) {
339+
// Update checked when the value changed to match the radio group's value
340+
this.checked = this.radioGroup.value == value;
341+
}
342+
if (this.checked) {
343+
this.radioGroup.selected = this;
344+
}
345+
}
346+
334347
}
335348
}
336349

0 commit comments

Comments
 (0)