Using *ngFor for create a series of radio buttons for angular2 using materialize-css framework
Plunker
Why it's not working
The status
variable in your *ngFor
loop is not being used in the for
attribute of your label
or the id
attribute of your input
.
There are two options to fix this:
Template expressions
You can use a template expression by putting the attributes in square brackets like this:
<input [id]="status">
which is what you did (correctly) with the value
attribute.
A template expression produces a value. Angular executes the expression and assigns it to a property of a binding target; the target might be an HTML element, a component, or a directive.
Interpolation
You can use interpolation by using double-curly braces like this:
<input id="{{status}}">
More generally, the material between the braces is a template expression that Angular first evaluates and then converts to a string.
What's the difference?
Checkout this answer for an explanation on the differences between these methods.
Full Template Html
<h2>Current Status</h2>
<p>{{maritalStatus?.status}}</p>
<h2>Options</h2>
<div *ngFor="let status of statuses; let indx = index">
<input #widget
class='with-gap'
name='statusGroup'
type='radio'
[id]='status'
[value]='status'
[(ngModel)]='maritalStatus.status'
/>
<label [for]='status'>{{status}}</label>
</div>
Full Component
import {Component} from '@angular/core';
import {Http} from '@angular/http'
import {bootstrap} from '@angular/platform-browser-dynamic';
@Component({
selector: 'material-app',
templateUrl: 'app.component.html'
})
export class AppComponent {
maritalStatus = { status: 'Nothing selected' };
statuses: string[] = [
'Single',
'Married',
'Divorced',
'Common-law',
'Visiting'
];
constructor() { }
}
Update - Angular 2 versions < 2.2.0
If you're using an Angular 2 version that is less than 2.2.0 you need to explicitly set the label
's for
attribute like this:
<label [attr.for]='status'>{{status}}</label>
because for
is not a property of label
elements.
Why?
Since Angular 2.2.0 (634b3bb), Angular maps the for
attribute to the related htmlFor
property.
It sounds like a lot of developers intuitively expected this, so they added it.
This was all pretty confusing for me at first, and this article by Pascal Precht really cleared up a lot of questions.
Related videos on Youtube
st_clair_clarke
Updated on June 04, 2022Comments
-
st_clair_clarke almost 2 years
Seasons greetings everyone!
I have the following code that constructs a single radio-button based on the materialize-css framework http://materializecss.com/forms.html#radio
<input name = 'group1' type = 'radio' id = 'test2'/> <label for = 'test2'>Yellow</label>
My attempt at using *ngFor is shown below:
statuses: string[] = [ 'Single', 'Married', 'Divorced', 'Common-law', 'Visiting' ]; <p>{{maritalStatus?.status}}</p> <div *ngFor = 'let status of statuses; let indx = index'> <input #widget class = 'with-gap' name = 'statusGroup' type = 'radio' id = 'status' [value] = 'status' [(ngModel)] = 'maritalStatus.status' (change) = 'radioBtnChange$.next(status)' /> <label for = 'status'>{{status}}</label> <p>{{status}}{{ indx}}</p> </div>
All buttons are created but only the first button (Single) can be selected.
How can I get the series of button to function as radio-buttons are expected to do?
Thanks
-
st_clair_clarke over 7 yearsGreat, and thanks. Two small tweaks I had to make to get it running - both id on the input and for on the label are attributes, NOT properties. Hence I had to prefix both with attr for it to work. See EDIT1 above for what works for me. Thanks
-
st_clair_clarke over 7 yearsActually, only a single tweak is necessary - the one for label since id is both a property and an attribute.
-
adriancarriger over 7 yearsI just found out that it's only needed if you're using an Angular 2 version that is less than 2.2.0.. I was pretty confused at first, and it turns out they added this as a feature recently. Thanks for pointing it out as it led to some fun learning about the framework!