Problem Description
In my Angular project, I’m using PrimeNG’s radio button component (p-radioButton) within my custom wrapper component (x-radio-button). This wrapper component implements the ControlValueAccessor interface.
Issue:
Everything works fine when using ngModel.
However, when I add a formControl, it correctly selects the default value, but when I select the other option, both radio buttons appear to be selected.
import { CommonModule } from '@angular/common';
import { FormsModule, NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { Component, EventEmitter, Input, Output, forwardRef } from '@angular/core';
import { RadioButtonModule } from 'primeng/radiobutton';
@Component({
selector: 'x-radio-button',
standalone: true,
imports: [CommonModule, FormsModule, RadioButtonModule],
templateUrl: './radio-button.component.html',
styleUrls: ['./radio-button.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RadioButtonComponent),
multi: true,
},
],
})
export class RadioButtonComponent implements ControlValueAccessor {
@Input() name: string;
@Input() value: any;
@Input() label: string;
@Input() inputId: string;
@Output() select = new EventEmitter<any>();
checked: boolean = false;
public _internalValue: any;
onChange = (value: any) => {};
onTouched = () => {};
// Value accessor interface
writeValue(value: any): void {
this._internalValue = value;
this.checked = this._internalValue === this.value;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
// Implement if necessary for disabled state
}
onRadioChange(): void {
this.checked = true;
this.onChange(this.value);
this.select.emit(this.value);
}
}
<p-radioButton
[name]="name"
[value]="value"
[(ngModel)]="_internalValue"
[inputId]="inputId"
(ngModelChange)="onRadioChange()">
</p-radioButton>
<label class="ml-2">{{ label }}</label>
Usage Scenario
<div>
<x-radio-button
[inputId]="'2'"
[value]="'http'"
formControlName="protocol">
</x-radio-button>
<x-radio-button
[inputId]="'1'"
[value]="'https'"
formControlName="protocol">
</x-radio-button>
</div>
this.parentForm.addControl(
'protocol',
new UntypedFormControl('http', Validators.required),
);
Expected Behavior
I expect only one of the radio buttons to be selected. When using the FormControl, I want the other button to automatically be disabled when one button is selected.
Help Needed
How can I fix this issue? I’m open to suggestions.