fix(forms): radio buttons with different names should not share state
Closes #7051
This commit is contained in:
parent
7a2ce7ff21
commit
6dc88f5b61
|
@ -43,11 +43,17 @@ export class RadioControlRegistry {
|
||||||
|
|
||||||
select(accessor: RadioControlValueAccessor) {
|
select(accessor: RadioControlValueAccessor) {
|
||||||
this._accessors.forEach((c) => {
|
this._accessors.forEach((c) => {
|
||||||
if (c[0].control.root === accessor._control.control.root && c[1] !== accessor) {
|
if (this._isSameGroup(c, accessor) && c[1] !== accessor) {
|
||||||
c[1].fireUncheck();
|
c[1].fireUncheck();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _isSameGroup(controlPair:[NgControl, RadioControlValueAccessor],
|
||||||
|
accessor: RadioControlValueAccessor) {
|
||||||
|
return controlPair[0].control.root === accessor._control.control.root &&
|
||||||
|
controlPair[1].name === accessor.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1203,44 +1203,75 @@ export function main() {
|
||||||
|
|
||||||
it("should support <type=radio>",
|
it("should support <type=radio>",
|
||||||
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
var t = `<form>
|
const t = `<form>
|
||||||
<input type="radio" name="food" ngControl="chicken" [(ngModel)]="data['chicken1']">
|
<input type="radio" name="food" ngControl="chicken" [(ngModel)]="data['chicken']">
|
||||||
<input type="radio" name="food" ngControl="fish" [(ngModel)]="data['fish1']">
|
<input type="radio" name="food" ngControl="fish" [(ngModel)]="data['fish']">
|
||||||
</form>
|
<input type="radio" name="food" ngControl="beef" [(ngModel)]="data['beef']">
|
||||||
<form>
|
<input type="radio" name="food" ngControl="pork" [(ngModel)]="data['pork']">
|
||||||
<input type="radio" name="food" ngControl="chicken" [(ngModel)]="data['chicken2']">
|
|
||||||
<input type="radio" name="food" ngControl="fish" [(ngModel)]="data['fish2']">
|
|
||||||
</form>`;
|
</form>`;
|
||||||
|
|
||||||
let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
|
const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
fixture.debugElement.componentInstance.data = {
|
fixture.debugElement.componentInstance.data = {
|
||||||
'chicken1': new RadioButtonState(false, 'chicken'),
|
'chicken': new RadioButtonState(false, 'chicken'),
|
||||||
'fish1': new RadioButtonState(true, 'fish'),
|
'fish': new RadioButtonState(true, 'fish'),
|
||||||
|
'beef': new RadioButtonState(false, 'beef'),
|
||||||
'chicken2': new RadioButtonState(false, 'chicken'),
|
'pork': new RadioButtonState(true, 'pork')
|
||||||
'fish2': new RadioButtonState(true, 'fish')
|
|
||||||
};
|
};
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
var input = fixture.debugElement.query(By.css("input"));
|
const input = fixture.debugElement.query(By.css("input"));
|
||||||
expect(input.nativeElement.checked).toEqual(false);
|
expect(input.nativeElement.checked).toEqual(false);
|
||||||
|
|
||||||
dispatchEvent(input.nativeElement, "change");
|
dispatchEvent(input.nativeElement, "change");
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
let data = fixture.debugElement.componentInstance.data;
|
const data = fixture.debugElement.componentInstance.data;
|
||||||
|
|
||||||
expect(data['chicken1']).toEqual(new RadioButtonState(true, 'chicken'));
|
expect(data['chicken']).toEqual(new RadioButtonState(true, 'chicken'));
|
||||||
expect(data['fish1']).toEqual(new RadioButtonState(false, 'fish'));
|
expect(data['fish']).toEqual(new RadioButtonState(false, 'fish'));
|
||||||
|
expect(data['beef']).toEqual(new RadioButtonState(false, 'beef'));
|
||||||
expect(data['chicken2']).toEqual(new RadioButtonState(false, 'chicken'));
|
expect(data['pork']).toEqual(new RadioButtonState(false, 'pork'));
|
||||||
expect(data['fish2']).toEqual(new RadioButtonState(true, 'fish'));
|
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should support multiple named <type=radio> groups",
|
||||||
|
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||||
|
const t = `<form>
|
||||||
|
<input type="radio" name="food" ngControl="chicken" [(ngModel)]="data['chicken']">
|
||||||
|
<input type="radio" name="food" ngControl="fish" [(ngModel)]="data['fish']">
|
||||||
|
<input type="radio" name="drink" ngControl="cola" [(ngModel)]="data['cola']">
|
||||||
|
<input type="radio" name="drink" ngControl="sprite" [(ngModel)]="data['sprite']">
|
||||||
|
</form>`;
|
||||||
|
|
||||||
|
const fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
|
||||||
|
tick();
|
||||||
|
|
||||||
|
fixture.debugElement.componentInstance.data = {
|
||||||
|
'chicken': new RadioButtonState(false, 'chicken'),
|
||||||
|
'fish': new RadioButtonState(true, 'fish'),
|
||||||
|
'cola': new RadioButtonState(false, 'cola'),
|
||||||
|
'sprite': new RadioButtonState(true, 'sprite')
|
||||||
|
};
|
||||||
|
fixture.detectChanges();
|
||||||
|
tick();
|
||||||
|
|
||||||
|
const input = fixture.debugElement.query(By.css("input"));
|
||||||
|
expect(input.nativeElement.checked).toEqual(false);
|
||||||
|
|
||||||
|
dispatchEvent(input.nativeElement, "change");
|
||||||
|
tick();
|
||||||
|
|
||||||
|
const data = fixture.debugElement.componentInstance.data;
|
||||||
|
|
||||||
|
expect(data['chicken']).toEqual(new RadioButtonState(true, 'chicken'));
|
||||||
|
expect(data['fish']).toEqual(new RadioButtonState(false, 'fish'));
|
||||||
|
expect(data['cola']).toEqual(new RadioButtonState(false, 'cola'));
|
||||||
|
expect(data['sprite']).toEqual(new RadioButtonState(true, 'sprite'));
|
||||||
|
})));
|
||||||
|
|
||||||
describe("setting status classes", () => {
|
describe("setting status classes", () => {
|
||||||
it("should work with single fields",
|
it("should work with single fields",
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
|
Loading…
Reference in New Issue