Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After adding [(ngModel)] to a radio button group, the default [checked] no longer works

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?

like image 393
msanford Avatar asked Feb 24 '17 16:02

msanford


People also ask

How do I make radio buttons not checked by default?

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> .

How to use angular material radio button?

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.

How do I group radio buttons in HTML?

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.


3 Answers

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.

like image 135
mickdev Avatar answered Oct 09 '22 09:10

mickdev


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.

like image 3
msanford Avatar answered Oct 09 '22 09:10

msanford


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>
like image 2
Mohammed Abir Avatar answered Oct 09 '22 11:10

Mohammed Abir