From a07ea1e065eaf99e617277ca44ee6559d6efe92d Mon Sep 17 00:00:00 2001 From: crisbeto Date: Fri, 25 Jan 2019 22:12:05 +0100 Subject: [PATCH] fix(button): not updating DOM node name if group name changes Fixes the underlying DOM node's name not being in sync with the group, if the group's name is set through the input. --- src/lib/button-toggle/button-toggle.spec.ts | 36 +++++++++++++++------ src/lib/button-toggle/button-toggle.ts | 5 ++- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/lib/button-toggle/button-toggle.spec.ts b/src/lib/button-toggle/button-toggle.spec.ts index c67babee0980..b27ded3acfd7 100644 --- a/src/lib/button-toggle/button-toggle.spec.ts +++ b/src/lib/button-toggle/button-toggle.spec.ts @@ -79,7 +79,7 @@ describe('MatButtonToggle with forms', () => { let buttonToggleInstances: MatButtonToggle[]; let testComponent: ButtonToggleGroupWithNgModel; let groupNgModel: NgModel; - let buttonToggleLabels: HTMLElement[]; + let innerButtons: HTMLElement[]; beforeEach(fakeAsync(() => { fixture = TestBed.createComponent(ButtonToggleGroupWithNgModel); @@ -92,7 +92,7 @@ describe('MatButtonToggle with forms', () => { buttonToggleDebugElements = fixture.debugElement.queryAll(By.directive(MatButtonToggle)); buttonToggleInstances = buttonToggleDebugElements.map(debugEl => debugEl.componentInstance); - buttonToggleLabels = buttonToggleDebugElements.map( + innerButtons = buttonToggleDebugElements.map( debugEl => debugEl.query(By.css('button')).nativeElement); fixture.detectChanges(); @@ -102,7 +102,7 @@ describe('MatButtonToggle with forms', () => { expect(testComponent.modelValue).toBeUndefined(); expect(testComponent.lastEvent).toBeUndefined(); - buttonToggleLabels[0].click(); + innerButtons[0].click(); fixture.detectChanges(); tick(); @@ -122,6 +122,18 @@ describe('MatButtonToggle with forms', () => { } }); + it('should update the name of radio DOM elements if the name of the group changes', () => { + expect(innerButtons.every(button => button.getAttribute('name') === groupInstance.name)) + .toBe(true, 'Expected all buttons to have the initial name.'); + + fixture.componentInstance.groupName = 'changed-name'; + fixture.detectChanges(); + + expect(groupInstance.name).toBe('changed-name'); + expect(innerButtons.every(button => button.getAttribute('name') === groupInstance.name)) + .toBe(true, 'Expected all buttons to have the new name.'); + }); + it('should check the corresponding button toggle on a group value change', () => { expect(groupInstance.value).toBeFalsy(); for (let buttonToggle of buttonToggleInstances) { @@ -152,7 +164,7 @@ describe('MatButtonToggle with forms', () => { expect(groupNgModel.pristine).toBe(true); expect(groupNgModel.touched).toBe(false); - buttonToggleLabels[2].click(); + innerButtons[2].click(); fixture.detectChanges(); tick(); @@ -162,7 +174,7 @@ describe('MatButtonToggle with forms', () => { })); it('should update the ngModel value when selecting a button toggle', fakeAsync(() => { - buttonToggleLabels[1].click(); + innerButtons[1].click(); fixture.detectChanges(); tick(); @@ -175,8 +187,8 @@ describe('MatButtonToggle with forms', () => { expect(groupElement.querySelectorAll('.mat-ripple-element').length).toBe(0); - dispatchMouseEvent(buttonToggleLabels[0], 'mousedown'); - dispatchMouseEvent(buttonToggleLabels[0], 'mouseup'); + dispatchMouseEvent(innerButtons[0], 'mousedown'); + dispatchMouseEvent(innerButtons[0], 'mouseup'); expect(groupElement.querySelectorAll('.mat-ripple-element').length).toBe(1); }); @@ -189,8 +201,8 @@ describe('MatButtonToggle with forms', () => { expect(groupElement.querySelectorAll('.mat-ripple-element').length).toBe(0); - dispatchMouseEvent(buttonToggleLabels[0], 'mousedown'); - dispatchMouseEvent(buttonToggleLabels[0], 'mouseup'); + dispatchMouseEvent(innerButtons[0], 'mousedown'); + dispatchMouseEvent(innerButtons[0], 'mouseup'); expect(groupElement.querySelectorAll('.mat-ripple-element').length).toBe(0); }); @@ -819,7 +831,10 @@ class ButtonTogglesInsideButtonToggleGroup { @Component({ template: ` - + {{option.label}} @@ -828,6 +843,7 @@ class ButtonTogglesInsideButtonToggleGroup { ` }) class ButtonToggleGroupWithNgModel { + groupName = 'group-name'; modelValue: string; options = [ {label: 'Red', value: 'red'}, diff --git a/src/lib/button-toggle/button-toggle.ts b/src/lib/button-toggle/button-toggle.ts index 0b42d51eb2ac..282d1fe74dcc 100644 --- a/src/lib/button-toggle/button-toggle.ts +++ b/src/lib/button-toggle/button-toggle.ts @@ -143,7 +143,10 @@ export class MatButtonToggleGroup implements ControlValueAccessor, OnInit, After this._name = value; if (this._buttonToggles) { - this._buttonToggles.forEach(toggle => toggle.name = this._name); + this._buttonToggles.forEach(toggle => { + toggle.name = this._name; + toggle._markForCheck(); + }); } } private _name = `mat-button-toggle-group-${_uniqueIdCounter++}`;