Skip to content

Commit e35221e

Browse files
committed
wip: proposal solution - simplyfied + tests
1 parent ad76115 commit e35221e

File tree

2 files changed

+72
-21
lines changed

2 files changed

+72
-21
lines changed

src/lib/components/radio/mdl-radio.component.spec.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('Component: MdlRadio', () => {
1010
beforeEach(async(() => {
1111
TestBed.configureTestingModule({
1212
imports: [ MdlRadioModule.forRoot(), FormsModule, ReactiveFormsModule ],
13-
declarations: [ MdlTestRadioComponent ],
13+
declarations: [ MdlTestRadioComponent, MdlTestUseSameRadioInGroupsComponent ],
1414
});
1515
}));
1616

@@ -161,6 +161,29 @@ describe('Component: MdlRadio', () => {
161161

162162
}));
163163

164+
165+
it('should be possible to use the same radio buttons in different groups', () => {
166+
let fixture = TestBed.createComponent(MdlTestUseSameRadioInGroupsComponent);
167+
fixture.detectChanges();
168+
169+
let g1t1Elem = fixture.debugElement.query(By.css('#g1t1')).nativeElement;
170+
let g1t2Elem = fixture.debugElement.query(By.css('#g1t2')).nativeElement;
171+
let g2t1Elem = fixture.debugElement.query(By.css('#g2t1')).nativeElement;
172+
173+
g1t1Elem.click();
174+
fixture.detectChanges();
175+
176+
expect(g1t1Elem.classList.contains('is-checked')).toBe(true, 'the clicked one should be selected');
177+
expect(g2t1Elem.classList.contains('is-checked')).toBe(false, 'the not clicked one should not be selected');
178+
179+
g1t2Elem.click();
180+
fixture.detectChanges();
181+
182+
expect(g1t1Elem.classList.contains('is-checked')).toBe(false, 'the not clicked one should not be selected');
183+
expect(g2t1Elem.classList.contains('is-checked')).toBe(false, 'the not clicked one should not be selected');
184+
185+
186+
});
164187
});
165188

166189

@@ -192,3 +215,36 @@ class MdlTestRadioComponent implements OnInit {
192215
}
193216

194217

218+
@Component({
219+
selector: 'test-radio',
220+
template: `
221+
<form [formGroup]="testForm">
222+
<div formGroupName="group1" mdl-radio-group>
223+
<mdl-radio formControlName="type" value="type1" id="g1t1"></mdl-radio>
224+
<mdl-radio formControlName="type" value="type2" id="g1t2"></mdl-radio>
225+
</div>
226+
<div formGroupName="group2">
227+
<mdl-radio formControlName="type" value="type1" id="g2t1"></mdl-radio>
228+
<mdl-radio formControlName="type" value="type2" id="g2t2"></mdl-radio>
229+
</div>
230+
</form>
231+
`
232+
})
233+
class MdlTestUseSameRadioInGroupsComponent implements OnInit {
234+
235+
public testForm: FormGroup;
236+
237+
constructor(private fb: FormBuilder) {}
238+
239+
public ngOnInit() {
240+
this.testForm = new FormGroup({
241+
group1: new FormGroup({
242+
type: new FormControl('')
243+
}),
244+
group2: new FormGroup({
245+
type: new FormControl('')
246+
})
247+
});
248+
}
249+
250+
}

src/lib/components/radio/mdl-radio.component.ts

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import {
1919
NG_VALUE_ACCESSOR,
2020
ControlValueAccessor,
21-
FormsModule
21+
FormsModule, FormGroupName
2222
} from '@angular/forms';
2323
import { CommonModule } from '@angular/common';
2424
import { BooleanProperty } from '../common/boolean-property';
@@ -34,13 +34,13 @@ const IS_FOCUSED = 'is-focused';
3434
@Injectable()
3535
export class MdlRadioGroupRegisty {
3636

37-
private defaultRadioGroup = new MdlRadioGroup();
38-
private radioComponents: {radio: MdlRadioComponent, group:MdlRadioGroup}[] = [];
37+
private defaultFormGroup = 'defaultFromGroup';
38+
private radioComponents: {radio: MdlRadioComponent, group: FormGroupName | string}[] = [];
3939

40-
public add(radioComponent: MdlRadioComponent, mdlRadioGroup: MdlRadioGroup) {
40+
public add(radioComponent: MdlRadioComponent, formGroupName: FormGroupName) {
4141
this.radioComponents.push({
4242
radio: radioComponent,
43-
group: mdlRadioGroup || this.defaultRadioGroup
43+
group: formGroupName || this.defaultFormGroup
4444
});
4545
}
4646

@@ -50,12 +50,12 @@ export class MdlRadioGroupRegisty {
5050
});
5151
}
5252

53-
public select(radioComponent: MdlRadioComponent, mdlRadioGroup: MdlRadioGroup) {
53+
public select(radioComponent: MdlRadioComponent, formGroupName: FormGroupName) {
5454
// unselect every radioComponent that is not the provided radiocomponent
5555
// and has the same name and is in teh same group.
56-
let testGroup = mdlRadioGroup || this.defaultRadioGroup;
56+
let groupToTest = formGroupName || this.defaultFormGroup;
5757
this.radioComponents.forEach( (component) => {
58-
if (component.radio.name === radioComponent.name && component.group === testGroup) {
58+
if (component.radio.name === radioComponent.name && component.group === groupToTest) {
5959
if (component.radio !== radioComponent) {
6060
component.radio.deselect(radioComponent.value);
6161
}
@@ -64,12 +64,6 @@ export class MdlRadioGroupRegisty {
6464
}
6565
}
6666

67-
@Directive({
68-
selector: '[formGroupName][mdl-radio-group]'
69-
})
70-
export class MdlRadioGroup {
71-
}
72-
7367
/*
7468
<mdl-radio name="group1" value="1" [(ngModel)]="radioOption">Value 1</mdl-radio>
7569
*/
@@ -123,7 +117,7 @@ export class MdlRadioComponent implements ControlValueAccessor, OnInit, OnDestro
123117
private elementRef: ElementRef,
124118
private renderer: Renderer,
125119
private ragioGroupRegisty: MdlRadioGroupRegisty,
126-
@Optional() private mdlRadioGroup: MdlRadioGroup) {
120+
@Optional() private formGroupName: FormGroupName) {
127121
this.el = elementRef.nativeElement;
128122
}
129123

@@ -132,8 +126,9 @@ export class MdlRadioComponent implements ControlValueAccessor, OnInit, OnDestro
132126
// a radio group without name is useless.
133127
this.checkName();
134128
// register the radio button - this is the only chance to unselect the
135-
// radio button that is no longer active
136-
this.ragioGroupRegisty.add(this, this.mdlRadioGroup);
129+
// radio button that is no longer active - scope the radio button with it's group
130+
// if there is one.
131+
this.ragioGroupRegisty.add(this, this.formGroupName);
137132
}
138133

139134
public ngOnDestroy() {
@@ -155,7 +150,7 @@ export class MdlRadioComponent implements ControlValueAccessor, OnInit, OnDestro
155150
// wrap the callback, so that we can call select on the registry
156151
this.onChangeCallback = () => {
157152
fn(this.value);
158-
this.ragioGroupRegisty.select(this, this.mdlRadioGroup);
153+
this.ragioGroupRegisty.select(this, this.formGroupName);
159154
};
160155
}
161156

@@ -209,8 +204,8 @@ export class MdlRadioComponent implements ControlValueAccessor, OnInit, OnDestro
209204

210205
@NgModule({
211206
imports: [CommonModule, FormsModule],
212-
exports: [MdlRadioComponent, MdlRadioGroup],
213-
declarations: [MdlRadioComponent, MdlRadioGroup]
207+
exports: [MdlRadioComponent],
208+
declarations: [MdlRadioComponent]
214209
})
215210
export class MdlRadioModule {
216211
public static forRoot(): ModuleWithProviders {

0 commit comments

Comments
 (0)