I have data like so:
const List: Array<Item> = [
{ id: 1, name: 'somename' }
...
]
Then html looks like this:
<ng-container *ngFor="let item of list; let i = index;">
<div class="grid">
<mat-checkbox *ngIf="item.id > 4;" #{{item.name}}
value="false"
type="checkbox">
</mat-checkbox>
<mat-form-field *ngIf="item.id <= 4">
<input formControlName="{{item.name}}" matInput value="" type="number"/>
</mat-form-field>
<mat-form-field *ngIf="item.id > 4 && item.name.checked">
<input formControlName="{{item.name}}" matInput value="" type="number"/>
</mat-form-field>
</div>
</ng-container>
NgFor iterates through the array and creates mat-checkbox's and mat-form-field's.
There is form-field for every item in the array but only some form-field items get checkbox.
Form-field that do not get checkbox are visible at all times.
Form-field that DO get checkbox are ONLY visible after corresponding checkbox is checked.
My problem is how do I get the form-field to be shown after it's checkbox is checked
?
The #{{item.name.checked}}
binding isn't working
Edit:
const List: Array<Item> = [
{ id: 1, name: 'somename', class: 'hide' }
...
]
<mat-checkbox #checkBoxId class="{{item.class}}"
type="checkbox">
</mat-checkbox>
SCSS
.hide {
display: none;
}
When you use a template reference variable inside a *ngFor
(or inside a @for
) the "scope" is relative to this loop
What mean this? that you use the "same" variable name (in the code checkBoxId
)
<ng-container *ngFor="let item of list; let i = index;">
<div class="grid">
<mat-checkbox *ngIf="item.id > 4;" #checkBoxId
value="false"
type="checkbox">
</mat-checkbox>
<!-- you can use--->
{{checkboxId.checked}}
<mat-form-field *ngIf="item.id > 4 && checkBoxId.checked">
<input formControlName="{{item.name}}" matInput
type="number"/>
</mat-form-field>
</ng-container>
NOTE: When you use ReactiveFormsControls not use "value", just give value to the formControl.
Update As it's indicate in comments (thanks for the advise @Dozobus) ther'e a problem when the mat-check is under a *ngIf. we can replace the *ngIf by [style.display]="i<=4?'non':null"
or use
<form [formGroup]="form">
<ng-container *ngFor="let control of form.controls|keyvalue;let i=index" >
<mat-form-field *ngIf="items[i].id<=4">
<input matInput [formControlName]="items[i].name" />
</mat-form-field><br/>
<ng-container *ngIf="items[i].id>4">
<section>
<mat-checkbox class="example-margin" #checkinId>Check me!</mat-checkbox>
</section>
<mat-form-field *ngIf="checkinId.checked">
<input matInput [formControlName]="items[i].name" />
</mat-form-field>
</ng-container>
</ng-container>
</form>
NOTE:In submit we need take account this mat-checkbox, we can use some like
//use ViewChildren to "reach" the checkboxes
@ViewChildren('checkinId') checkboxes!:QueryList<MatCheckbox>
submit()
{
const data={...this.form.value}
this.items.forEach((x:any,index:number)=>{
if (x.id>4)
{
const checkBox=this.checkboxes.find((_,i:number)=>i==index-4)
if (checkBox && !checkBox.checked)
data[x.name]=""
}
})
...do something with "data"
}
NOTE2: In stackblitz I put diferents ways to mannage the problem using the new @for
and @if