Angular 2: how to create radio buttons from enum and add two-way binding?
Asked Answered
A

2

12

I'm trying to use Angular2 syntax to create radio buttons from an enum definition, and bind the value to a property that has the type of that enum.

My html contains:

<div class="from_elem">
    <label>Motif</label><br>
    <div  *ngFor="let choice of motifChoices">
        <input type="radio" name="motif" [(ngModel)]="choice.value"/>{{choice.motif}}<br>
    </div>
</div>

In my @Component, I declared the set of choices and values:

private motifChoices: any[] = [];

And in the constructor of my @Component, I filled the choices the following way:

constructor( private interService: InterventionService )
{
    this.motifChoices =
        Object.keys(MotifIntervention).filter( key => isNaN( Number( key )))
            .map( key => { return { motif: key, value: false } });
}

The radio buttons are displayed correctly, now I seek to bind the value selected to a property. But when I click one of the buttons the value choice.value is set to undefined.

Aloise answered 8/9, 2016 at 13:12 Comment(0)
A
23

Ok finally I found out the solution. I am currenly using Angular 2 RC5.

The enum value I want to bind my radio is the property:

intervention.rapport.motifIntervention : MotifInterventions

In my @Component I declared private members to give access to enum definition in the html template:

export class InterventionDetails
{
    private MotifIntervention = MotifIntervention;
    private MotifInterventionValues = Object.values(MotifIntervention).filter( e => typeof( e ) == "number" );

    // model object:
    private intervention: Intervention;

Here is HTML code for the radio buttons:

<div *ngFor="let choice of MotifInterventionValues">
    <input type="radio"
           [(ngModel)]="intervention.rapport.motifIntervention"
           [checked]="intervention.rapport.motifIntervention==choice"
           [value]="choice" />
    {{MotifIntervention[choice]}}<br>
</div>
  • [(ngModel)]="intervention.rapport.motifIntervention" is two-way binding, it is required to update the property in the model (in my case intervention.rapport.motifIntervention)

  • [checked]="intervention.rapport.motifIntervention==choice" is required to update the radio buttons component if the value intervention.rapport.motifIntervention is modified externally.

  • [value]="choice" is the value that is assigned to my property when the radio button is selected.

  • {{MotifIntervention[choice]}} is the label of the radio button

Aloise answered 8/9, 2016 at 16:57 Comment(6)
This saved my life [value]="choice" ... very strange the api doc doesn't even show this: angular.io/docs/ts/latest/api/forms/index/…Holliehollifield
from Object.values, I get "Property 'values' does not exist on type 'ObjectConstructor'."Bedraggled
I also get "Property 'values' does not exist on type 'ObjectConstructor"Squalor
It may have changed to [ngValue] since september. I will update my poste as soon as it's validated in my app.Headwater
The problem with "Property 'values' does not exist on type 'ObjectConstructor'." can be solved by using (<any>Object).values(MotifIntervention).filter(e => typeof(e) == 'number');Lexy
I tried this code exactly, just changing the enum for my own. @AnthonyBrenelière, do you have an update on this code for angular6+Hagiarchy
B
1

A bit late to the party, but this worked for me:

  <tr *ngFor="let Item of Items; let idx = index" style="line-height: 10px;">
    <td style="font-size:11px;padding-right: 10px;">{{ GetOption(Item) }}</td>                      
    <td><input type="radio" [attr.name]="ComponentID" [id]="ComponentID"
      [value]="GetValue(Item)" [checked]="value == GetValue(Item)" (change)="SelectionChange(GetValue(Item))"></td>           
  </tr>

Where:

  • Items is an array of options
  • ComponentID is the name of the component
  • GetOption is a function that returns the caption that the option should use
  • GetValue is a function that returns the value that the option should use
  • SelectionChanged is used to update the model

Note that I don't use [(ngModel)]

Beilul answered 15/5, 2018 at 0:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.