Skip to content

Commit 7163cd4

Browse files
authored
Merge pull request #1677 from IgniteUI/bkulov/radio-group
New directive: IgxRadioGroupDirective
2 parents b482e38 + 45a6c7d commit 7163cd4

File tree

11 files changed

+789
-13
lines changed

11 files changed

+789
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
All notable changes for each version of this project will be documented in this file.
44
## 6.1.0
55
- `igxOverlay` service added. **igxOverlayService** allows you to show any component above all elements in page. For more detailed information see the [official documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay.html)
6+
- Added **igxRadioGroup** directive. It allows better control over its child `igxRadio` components and support template-driven and reactive forms.
67
- Added `column moving` feature to `igxGrid`, enabled on a per-column level. **Column moving** allows you to reorder the `igxGrid` columns via standard drag/drop mouse or touch gestures.
78
For more detailed information see the [official documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid_column_moving.html).
89
- `igxGrid` filtering operands
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
import { Component, ViewChild } from '@angular/core';
2+
import { async, TestBed, fakeAsync, tick } from '@angular/core/testing';
3+
import { IgxRadioModule, IgxRadioGroupDirective } from './radio-group.directive';
4+
import { FormsModule, ReactiveFormsModule, FormGroup, FormBuilder } from '@angular/forms';
5+
6+
describe('IgxRadioGroupDirective', () => {
7+
beforeEach(async(() => {
8+
TestBed.configureTestingModule({
9+
declarations: [
10+
RadioGroupComponent,
11+
RadioGroupWithModelComponent,
12+
RadioGroupReactiveFormsComponent
13+
],
14+
imports: [
15+
IgxRadioModule,
16+
FormsModule,
17+
ReactiveFormsModule
18+
]
19+
})
20+
.compileComponents();
21+
}));
22+
23+
it('Properly initialize the radio group buttons\' properties.', fakeAsync(() => {
24+
const fixture = TestBed.createComponent(RadioGroupComponent);
25+
const radioInstance = fixture.componentInstance.radioGroup;
26+
27+
fixture.detectChanges();
28+
tick();
29+
30+
expect(radioInstance.radioButtons).toBeDefined();
31+
expect(radioInstance.radioButtons.length).toEqual(3);
32+
33+
const allRequiredButtons = radioInstance.radioButtons.filter((btn) => btn.required);
34+
expect(allRequiredButtons.length).toEqual(radioInstance.radioButtons.length);
35+
36+
const allButtonsWithGroupName = radioInstance.radioButtons.filter((btn) => btn.name === radioInstance.name);
37+
expect(allButtonsWithGroupName.length).toEqual(radioInstance.radioButtons.length);
38+
39+
const allButtonsWithGroupLabelPos = radioInstance.radioButtons.filter((btn) => btn.labelPosition === radioInstance.labelPosition);
40+
expect(allButtonsWithGroupLabelPos.length).toEqual(radioInstance.radioButtons.length);
41+
42+
const buttonWithGroupValue = radioInstance.radioButtons.find((btn) => btn.value === radioInstance.value);
43+
expect(buttonWithGroupValue).toBeDefined();
44+
expect(buttonWithGroupValue).toEqual(radioInstance.selected);
45+
}));
46+
47+
it('Setting radioGroup\'s properties should affect all radio buttons.', fakeAsync(() => {
48+
const fixture = TestBed.createComponent(RadioGroupComponent);
49+
const radioInstance = fixture.componentInstance.radioGroup;
50+
51+
fixture.detectChanges();
52+
tick();
53+
54+
expect(radioInstance.radioButtons).toBeDefined();
55+
56+
// name
57+
radioInstance.name = 'newGroupName';
58+
fixture.detectChanges();
59+
60+
const allButtonsWithNewName = radioInstance.radioButtons.filter((btn) => btn.name === 'newGroupName');
61+
expect(allButtonsWithNewName.length).toEqual(radioInstance.radioButtons.length);
62+
63+
// required
64+
radioInstance.required = true;
65+
fixture.detectChanges();
66+
67+
const allRequiredButtons = radioInstance.radioButtons.filter((btn) => btn.required);
68+
expect(allRequiredButtons.length).toEqual(radioInstance.radioButtons.length);
69+
70+
// labelPosition
71+
radioInstance.labelPosition = 'after';
72+
fixture.detectChanges();
73+
74+
const allAfterButtons = radioInstance.radioButtons.filter((btn) => btn.labelPosition === 'after');
75+
expect(allAfterButtons.length).toEqual(radioInstance.radioButtons.length);
76+
77+
// disabled
78+
radioInstance.disabled = true;
79+
fixture.detectChanges();
80+
81+
const allDisabledButtons = radioInstance.radioButtons.filter((btn) => btn.disabled);
82+
expect(allDisabledButtons.length).toEqual(radioInstance.radioButtons.length);
83+
}));
84+
85+
it('Set value should change selected property and emit change event.', fakeAsync(() => {
86+
const fixture = TestBed.createComponent(RadioGroupComponent);
87+
const radioInstance = fixture.componentInstance.radioGroup;
88+
89+
fixture.detectChanges();
90+
tick();
91+
92+
expect(radioInstance.value).toBeDefined();
93+
expect(radioInstance.value).toEqual('Baz');
94+
95+
expect(radioInstance.selected).toBeDefined();
96+
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.last);
97+
98+
spyOn(radioInstance.change, 'emit');
99+
100+
radioInstance.value = 'Foo';
101+
fixture.detectChanges();
102+
103+
expect(radioInstance.value).toEqual('Foo');
104+
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
105+
expect(radioInstance.change.emit).toHaveBeenCalled();
106+
}));
107+
108+
it('Set selected property should change value and emit change event.', fakeAsync(() => {
109+
const fixture = TestBed.createComponent(RadioGroupComponent);
110+
const radioInstance = fixture.componentInstance.radioGroup;
111+
112+
fixture.detectChanges();
113+
tick();
114+
115+
expect(radioInstance.value).toBeDefined();
116+
expect(radioInstance.value).toEqual('Baz');
117+
118+
expect(radioInstance.selected).toBeDefined();
119+
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.last);
120+
121+
spyOn(radioInstance.change, 'emit');
122+
123+
radioInstance.selected = radioInstance.radioButtons.first;
124+
fixture.detectChanges();
125+
126+
expect(radioInstance.value).toEqual('Foo');
127+
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
128+
expect(radioInstance.change.emit).toHaveBeenCalled();
129+
}));
130+
131+
it('Clicking on a radio button should update the model.', fakeAsync(() => {
132+
const fixture = TestBed.createComponent(RadioGroupWithModelComponent);
133+
const radioInstance = fixture.componentInstance.radioGroup;
134+
135+
fixture.detectChanges();
136+
tick();
137+
138+
radioInstance.radioButtons.first.nativeLabel.nativeElement.click();
139+
fixture.detectChanges();
140+
tick();
141+
142+
expect(radioInstance.value).toEqual('Winter');
143+
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
144+
}));
145+
146+
it('Updating the model should select a radio button.', fakeAsync(() => {
147+
const fixture = TestBed.createComponent(RadioGroupWithModelComponent);
148+
const radioInstance = fixture.componentInstance.radioGroup;
149+
150+
fixture.detectChanges();
151+
tick();
152+
153+
fixture.componentInstance.personBob.favoriteSeason = 'Winter';
154+
fixture.detectChanges();
155+
tick();
156+
157+
expect(radioInstance.value).toEqual('Winter');
158+
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
159+
}));
160+
161+
it('Properly update the model when radio group is hosted in Reactive forms.', fakeAsync(() => {
162+
const fixture = TestBed.createComponent(RadioGroupReactiveFormsComponent);
163+
164+
fixture.detectChanges();
165+
tick();
166+
167+
expect(fixture.componentInstance.personForm).toBeDefined();
168+
expect(fixture.componentInstance.model).toBeDefined();
169+
expect(fixture.componentInstance.newModel).toBeUndefined();
170+
171+
fixture.componentInstance.personForm.patchValue({ favoriteSeason: fixture.componentInstance.seasons[0] });
172+
fixture.componentInstance.updateModel();
173+
fixture.detectChanges();
174+
tick();
175+
176+
expect(fixture.componentInstance.newModel).toBeDefined();
177+
expect(fixture.componentInstance.newModel.name).toEqual(fixture.componentInstance.model.name);
178+
expect(fixture.componentInstance.newModel.favoriteSeason).toEqual(fixture.componentInstance.seasons[0]);
179+
}));
180+
});
181+
182+
@Component({
183+
template: `<igx-radio-group #radioGroup name="radioGroup" value="Baz" required="true" labelPosition="before">
184+
<igx-radio *ngFor="let item of ['Foo', 'Bar', 'Baz']" value="{{item}}">
185+
{{item}}
186+
</igx-radio>
187+
</igx-radio-group>
188+
`
189+
})
190+
class RadioGroupComponent {
191+
@ViewChild('radioGroup', { read: IgxRadioGroupDirective }) public radioGroup: IgxRadioGroupDirective;
192+
}
193+
194+
class Person {
195+
name: string;
196+
favoriteSeason: string;
197+
}
198+
199+
@Component({
200+
template: ` <igx-radio-group #radioGroupSeasons name="radioGroupSeasons" [(ngModel)]="personBob.favoriteSeason">
201+
<igx-radio *ngFor="let item of seasons" value="{{item}}">
202+
{{item}}
203+
</igx-radio>
204+
</igx-radio-group>
205+
`
206+
})
207+
class RadioGroupWithModelComponent {
208+
seasons = [
209+
'Winter',
210+
'Spring',
211+
'Summer',
212+
'Autumn',
213+
];
214+
215+
@ViewChild('radioGroupSeasons', { read: IgxRadioGroupDirective }) public radioGroup: IgxRadioGroupDirective;
216+
217+
personBob: Person = { name: 'Bob', favoriteSeason: 'Summer' };
218+
}
219+
220+
@Component({
221+
template: `
222+
<form [formGroup]="personForm">
223+
<igx-radio-group formControlName="favoriteSeason" name="radioGroupReactive">
224+
<igx-radio *ngFor="let item of seasons" value="{{item}}">
225+
{{item}}
226+
</igx-radio>
227+
</igx-radio-group>
228+
</form>
229+
`
230+
})
231+
class RadioGroupReactiveFormsComponent {
232+
seasons = [
233+
'Winter',
234+
'Spring',
235+
'Summer',
236+
'Autumn',
237+
];
238+
239+
newModel: Person;
240+
model: Person = { name: 'Kirk', favoriteSeason: this.seasons[1] };
241+
personForm: FormGroup;
242+
243+
constructor(private _formBuilder: FormBuilder) {
244+
this._createForm();
245+
}
246+
247+
updateModel() {
248+
const formModel = this.personForm.value;
249+
250+
this.newModel = {
251+
name: formModel.name as string,
252+
favoriteSeason: formModel.favoriteSeason as string
253+
};
254+
}
255+
256+
private _createForm() {
257+
// create form
258+
this.personForm = this._formBuilder.group({
259+
name: '',
260+
favoriteSeason: ''
261+
});
262+
263+
// simulate model loading from service
264+
this.personForm.setValue({
265+
name: this.model.name,
266+
favoriteSeason: this.model.favoriteSeason
267+
});
268+
}
269+
}

0 commit comments

Comments
 (0)