I'm working on a small reusable Component which styles radio buttons and emits the selected values.
import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
@Component({
moduleId: module.id,
selector: 'button-select',
template: `<div class="toggle-group">
<div *ngFor="let choice of choices">
<input type="radio"
id="{{ groupName + choice }}"
name="{{groupName}}"
value="{{ choice }}"
[checked]="choice === defaultChoice"
[(ngModel)]="value"
(ngModelChange)="choose($event)" />
<label class="toggle-button"
for="{{ groupName + choice }}">{{ choice }}</label>
</div>
</div>`,
styleUrls: [
'editableField.css',
'buttonSelect.css'
]
})
export class ButtonSelectComponent implements OnInit {
@Input() choices: string[];
@Input() defaultChoice: string;
@Input() groupName: string;
@Input() value: string;
@Output() valueChosen: EventEmitter<any> = new EventEmitter();
ngOnInit() {
this.choose(this.defaultChoice);
}
private choose(value: string) {
this.valueChosen.emit(value);
}
}
The component is implemented like so:
<button-select #statusFilter
[choices]="['All', 'Active', 'Draft']"
[defaultChoice]="'All'"
[groupName]="'statusFilter'"
(valueChosen)="filterChosen('statusFilter', $event)"
</button-select>
Before adding [(ngModel)]="value" (ngModelChange)="choose($event)"
to the button-select Component, the [checked]="choice === defaultChoice"
directive correctly set the checked
attribute on the relevant <input />
.
After adding the [(ngModel)]
, only ng-reflect-checked="true"
gets set, which prevents the visual styling from showing the default value (since my CSS uses a pseudo-selector).
Changing [(ngModel)]
for [ngModel]
had no effect.
Why did this happen and how can I fix it?
You can check a radio button by default by adding the checked HTML attribute to the <input> element. You can disable a radio button by adding the disabled HTML attribute to both the <label> and the <input> .
Radio-button labelThe label can be positioned before or after the radio-button by setting the labelPosition property to 'before' or 'after' . If you don't want the label to appear next to the radio-button, you can use aria-label or aria-labelledby to specify an appropriate label.
Note: The radio group must have share the same name (the value of the name attribute) to be treated as a group. Once the radio group is created, selecting any radio button in that group automatically deselects any other selected radio button in the same group.
I think, you don't need this [checked]="choice === defaultChoice"
. Try this :
<input type="radio"
id="{{ groupName + choice }}"
name="{{groupName}}"
[value]="choice"
[(ngModel)]="defaultChoice"
(ngModelChange)="choose($event)" />
When [value] = [(ngModel)]
the radio is selected.
I was able to emit the value and retain the default styling with minimal changes by altering the input's template to:
<input type="radio"
id="{{ groupName + choice }}"
name="{{groupName}}"
value="{{ choice }}"
[checked]="choice === defaultChoice"
(click)="choose($event['target']['value'])" />
...which I find kind of hacky. It also doesn't explain why adding data/property binding broke it, so I'm open to more suggestions.
export class ConfirmationmodalComponent implements OnInit {
client_notification: any = false;
candidate_notification: any = false;
cancel_associated_session: any = false;
constructor(
) {}
ngOnInit(): void {
}
}
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
id="inlineRadio1"
name="cancel_associated_session"
[(ngModel)]="cancel_associated_session"
[value]="true"
/>
<label class="form-check-label" for="inlineRadio1">
Yes
</label>
</div>
<div class="form-check form-check-inline">
<input
class="form-check-input"
type="radio"
id="inlineRadio2"
name="cancel_associated_session"
[(ngModel)]="cancel_associated_session"
[value]="false"
/>
<label class="form-check-label" for="inlineRadio2">
No
</label>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With