Skip to content

Commit 2860418

Browse files
karaIgorMinar
authored andcommitted
fix(forms): disable all radios with disable()
1 parent 39e251e commit 2860418

File tree

3 files changed

+89
-6
lines changed

3 files changed

+89
-6
lines changed

modules/@angular/forms/src/model.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ export abstract class AbstractControl {
334334
}
335335

336336
this._updateAncestors(onlySelf);
337-
this._onDisabledChange(true);
337+
this._onDisabledChange.forEach((changeFn) => changeFn(true));
338338
}
339339

340340
/**
@@ -350,7 +350,7 @@ export abstract class AbstractControl {
350350
this.updateValueAndValidity({onlySelf: true, emitEvent: emitEvent});
351351

352352
this._updateAncestors(onlySelf);
353-
this._onDisabledChange(false);
353+
this._onDisabledChange.forEach((changeFn) => changeFn(false));
354354
}
355355

356356
private _updateAncestors(onlySelf: boolean) {
@@ -595,7 +595,7 @@ export abstract class AbstractControl {
595595
}
596596

597597
/** @internal */
598-
_onDisabledChange(isDisabled: boolean): void {}
598+
_onDisabledChange: Function[] = [];
599599

600600
/** @internal */
601601
_isBoxedValue(formState: any): boolean {
@@ -770,14 +770,16 @@ export class FormControl extends AbstractControl {
770770
*/
771771
_clearChangeFns(): void {
772772
this._onChange = [];
773-
this._onDisabledChange = null;
773+
this._onDisabledChange = [];
774774
this._onCollectionChange = () => {};
775775
}
776776

777777
/**
778778
* Register a listener for disabled events.
779779
*/
780-
registerOnDisabledChange(fn: (isDisabled: boolean) => void): void { this._onDisabledChange = fn; }
780+
registerOnDisabledChange(fn: (isDisabled: boolean) => void): void {
781+
this._onDisabledChange.push(fn);
782+
}
781783

782784
/**
783785
* @internal

modules/@angular/forms/test/reactive_integration_spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,54 @@ export function main() {
10221022

10231023
});
10241024

1025+
it('should disable all radio buttons when disable() is called', () => {
1026+
const fixture = TestBed.createComponent(FormControlRadioButtons);
1027+
const form =
1028+
new FormGroup({food: new FormControl('fish'), drink: new FormControl('cola')});
1029+
fixture.componentInstance.form = form;
1030+
fixture.detectChanges();
1031+
1032+
const inputs = fixture.debugElement.queryAll(By.css('input'));
1033+
expect(inputs[0].nativeElement.disabled).toEqual(false);
1034+
expect(inputs[1].nativeElement.disabled).toEqual(false);
1035+
expect(inputs[2].nativeElement.disabled).toEqual(false);
1036+
expect(inputs[3].nativeElement.disabled).toEqual(false);
1037+
1038+
form.get('food').disable();
1039+
expect(inputs[0].nativeElement.disabled).toEqual(true);
1040+
expect(inputs[1].nativeElement.disabled).toEqual(true);
1041+
expect(inputs[2].nativeElement.disabled).toEqual(false);
1042+
expect(inputs[3].nativeElement.disabled).toEqual(false);
1043+
1044+
form.disable();
1045+
expect(inputs[0].nativeElement.disabled).toEqual(true);
1046+
expect(inputs[1].nativeElement.disabled).toEqual(true);
1047+
expect(inputs[2].nativeElement.disabled).toEqual(true);
1048+
expect(inputs[3].nativeElement.disabled).toEqual(true);
1049+
1050+
form.enable();
1051+
expect(inputs[0].nativeElement.disabled).toEqual(false);
1052+
expect(inputs[1].nativeElement.disabled).toEqual(false);
1053+
expect(inputs[2].nativeElement.disabled).toEqual(false);
1054+
expect(inputs[3].nativeElement.disabled).toEqual(false);
1055+
});
1056+
1057+
it('should disable all radio buttons when initially disabled', () => {
1058+
const fixture = TestBed.createComponent(FormControlRadioButtons);
1059+
const form = new FormGroup({
1060+
food: new FormControl({value: 'fish', disabled: true}),
1061+
drink: new FormControl('cola')
1062+
});
1063+
fixture.componentInstance.form = form;
1064+
fixture.detectChanges();
1065+
1066+
const inputs = fixture.debugElement.queryAll(By.css('input'));
1067+
expect(inputs[0].nativeElement.disabled).toEqual(true);
1068+
expect(inputs[1].nativeElement.disabled).toEqual(true);
1069+
expect(inputs[2].nativeElement.disabled).toEqual(false);
1070+
expect(inputs[3].nativeElement.disabled).toEqual(false);
1071+
});
1072+
10251073
});
10261074

10271075
describe('custom value accessors', () => {

modules/@angular/forms/test/template_integration_spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,39 @@ export function main() {
445445
expect(input.nativeElement.disabled).toEqual(false);
446446
}));
447447

448+
it('should disable radio controls properly with programmatic call', fakeAsync(() => {
449+
const fixture = TestBed.createComponent(NgModelRadioForm);
450+
fixture.componentInstance.food = 'fish';
451+
fixture.detectChanges();
452+
tick();
453+
454+
const form = fixture.debugElement.children[0].injector.get(NgForm);
455+
form.control.get('food').disable();
456+
tick();
457+
458+
const inputs = fixture.debugElement.queryAll(By.css('input'));
459+
expect(inputs[0].nativeElement.disabled).toBe(true);
460+
expect(inputs[1].nativeElement.disabled).toBe(true);
461+
expect(inputs[2].nativeElement.disabled).toBe(false);
462+
expect(inputs[3].nativeElement.disabled).toBe(false);
463+
464+
form.control.disable();
465+
tick();
466+
467+
expect(inputs[0].nativeElement.disabled).toBe(true);
468+
expect(inputs[1].nativeElement.disabled).toBe(true);
469+
expect(inputs[2].nativeElement.disabled).toBe(true);
470+
expect(inputs[3].nativeElement.disabled).toBe(true);
471+
472+
form.control.enable();
473+
tick();
474+
475+
expect(inputs[0].nativeElement.disabled).toBe(false);
476+
expect(inputs[1].nativeElement.disabled).toBe(false);
477+
expect(inputs[2].nativeElement.disabled).toBe(false);
478+
expect(inputs[3].nativeElement.disabled).toBe(false);
479+
}));
480+
448481
});
449482

450483
describe('radio controls', () => {
@@ -928,7 +961,7 @@ class NgModelOptionsStandalone {
928961
<form>
929962
<input type="radio" name="food" [(ngModel)]="food" value="chicken">
930963
<input type="radio" name="food" [(ngModel)]="food" value="fish">
931-
964+
932965
<input type="radio" name="drink" [(ngModel)]="drink" value="cola">
933966
<input type="radio" name="drink" [(ngModel)]="drink" value="sprite">
934967
</form>

0 commit comments

Comments
 (0)