I'm a bit stuck with my problem. I'm working on view like that:
I'm fetching data from API so I will have multiple options and suboptions. However I want suboption to appear only when parent checkbox is checked. I tried to use *ngIf:
<ul *ngFor="let job of jobs; let i = index">
<input type="checkbox" id="{{i}}" value="{{job.name}}"><label
for="{{i}}">{{job.name}}</label>
<ul *ngIf="CONDITION HERE">
<li *ngFor="let child of job.children"><label><input type="checkbox">
{{child.name}}</label></li>
<li *ngFor="let child of job.children"><label><input type="checkbox">
{{child.name}}</label></li>
</ul>
</ul>
But I can't identify what condition could I use. Is there a simple solution to solve that?
@edit Let me clarify. I might have multiple options like that:
Using a flag won't work, because each parent options would have to use unique boolean variable.
CodePudding user response:
You can achieve this with the help of template reference variable. Assign a template variable to all repetitive parent input checkbox elements.
Use this variable to check the status of the checkbox (checked/unchecked) and based on this show/hide the children.
Please note that you will have to also use
(change)="true"
for parent checkbox. Without this the checked/unchecked property of the checkbox will not change.
Modify your template like this:
<ul *ngFor="let job of jobs; let i = index">
<input type="checkbox" id="{{ i }}" value="{{ job.name }}" (change)="true" #checkBox/><label
for="{{ i }}"
>{{ job.name }}</label
>
<ul *ngIf="checkBox.checked">
<li *ngFor="let child of job.children">
<label><input type="checkbox" /> {{ child.name }}</label>
</li>
<li *ngFor="let child of job.children">
<label><input type="checkbox" /> {{ child.name }}</label>
</li>
</ul>
</ul>
Stackblitz: https://stackblitz.com/edit/angular-x3coln?file=src/app/app.component.html
CodePudding user response:
Add a checked property in your model, then based on if it is checked or not, display the child checkbox.
Ex (assuming your model is called Job)
export class Job {
isChecked: boolean = false;
}
Then your ngIf would be *ngIf="job.isChecked"
CodePudding user response:
<input [checked]="checkedMain" type="checkbox" id="{{i}}" value="{{job.name}}"><label
for="{{i}}">{{job.name}}</label>
<ul *ngIf="checkedMain">
<li *ngFor="let child of job.children"><label><input type="checkbox">
{{child.name}}</label></li>
<li *ngFor="let child of job.children"><label><input type="checkbox">
{{child.name}}</label></li>
</ul>
CodePudding user response:
NgIf
A structural directive that conditionally includes a template based on the value of an expression coerced to Boolean.
You can just check if job exists.
<ul *ngIf="job"> //should do the job for you as it will be coerced to true if job exists.
CodePudding user response:
You can do like this
suppose your list is like below from API
this.list = [
{
id: 1,
title: 'parent1',
checked: false,
children:["A","B","C"]
},
{
id: 2,
title: 'parent2',
checked: false,
children:["A","B","C"]
},
{
id: 3,
title: 'parent3',
checked: false,
children:["A","B","C"]
}
]
Your html code should be like below to hide/unhide the children based on parent state.
<ul *ngFor="let item of list">
<input type="checkbox" [(ngModel)]="item.checked"/>{{item.title}}
<ng-template [ngIf]="item.checked">
<li *ngFor="let item1 of item.children">
<input type="checkbox" >{{item1}}
</li>
</ng-template>
</ul>
CodePudding user response:
Ideal way of achieving this would be to keep a isChecked property to track state of checkboxes for each option.
<div>
<ul *ngFor="let option of options; let i = index">
<input type="checkbox" id="{{ i }}" [(ngModel)]="option.isChecked" /><label
for="{{ i }}"
>{{ option.name }}</label
>
<ul *ngIf="option.isChecked">
<li *ngFor="let subOption of option.subOptions">
<label>{{ subOption }}</label>
</li>
</ul>
</ul>
</div>
options = [{ name: 'Type1', subOptions: [1, 2, 3], isChecked: false }];
Method 2: Incase if you do not want to modify the list of jobs/options
<div>
<ul *ngFor="let option of options; let i = index">
<input type="checkbox" id="{{ i }}" [(ngModel)]="state[option.name]" />
<label
for="{{ i }}"
>{{ option.name }}</label
>
<ul *ngIf="state[option.name]">
<li *ngFor="let subOption of option.subOptions">
<label>{{ subOption }}</label>
</li>
</ul>
</ul>
</div>
options = [{ name: 'Type1', subOptions: [1, 2, 3]}];
state = {};