I have a UI where initially a User has to check some checkboxes. The checkboxes have sequential IDs. The JSON Structure for it is as follows:
{
"categories": [{
"name": "Product",
"labels": [{
"id": 1,
"name": "I work on an asset (capital good).",
"checked": false
}, {
"id": 2,
"name": "I work on a consumer product.",
"checked": false
}, {
"id": 3,
"name": "I am not sure what type of product I work on.",
"checked": false
}
]
}, {
"name": "Goal",
"labels": [{
"id": 4,
"name": "I want to improve the product's reliability.",
"checked": false
}, {
"id": 5,
"name": "I need information to identify root causes.",
"checked": false
}, {
"id": 6,
"name": "I need information about the product's environment.",
"checked": false
}, {
"id": 7,
"name": "I need information about customer requirements.",
"checked": false
}, {
"id": 8,
"name": "I need quantified information.",
"checked": false
}, {
"id": 9,
"name": "I am not sure what I need.",
"checked": false
}
]
}
]
}
I render it Angular using the following Code:
component.html
<div class="row mt-lg-auto" *ngFor="let filter of filters['categories']">
<div class="col-lg-12">
<h4>
{{filter['name']}}
</h4>
<div *ngFor="let label of filter['labels']">
<div class="form-check">
<input class="form-check-input"
type="checkbox"
value="{{label['id']}}"
id="{{label['id']}}"
[(ngModel)]="label['checked']"
(change)="changeCheck(label['id'], $event)"
>
<label class="form-check-label" for="{{label['id']}}">
{{label['name']}}
</label>
</div>
</div>
</div>
</div>
component.ts
I directly import the JSON file from src/assets/
folder and save the id
to a Set
in order to avoid duplicate values when the user selects a checkbox.
import { Component, OnInit } from '@angular/core';
import * as FilterFunc from 'src/assets/FilterFunction.json';
const Filters: any = FilterFunc;
@Component({
selector: 'explore-step1',
templateUrl: './explore-step1.component.html',
styleUrls: ['./explore-step1.component.css']
})
export class ExploreStep1Component implements OnInit {
filters = Filters.default;
selections = new Set();
constructor() {
}
ngOnInit(): void {
}
changeCheck(id: number, event: any) {
(event.target.checked) ?
this.selections.add(id):
this.selections.delete(id);
console.log(this.selections);
}
}
I am using ngx-treeview
to render a tree view for a fixed JSON file that has the following structure:
GitHub Gist of the Complete Recursive JSON
Here on the children in the most depth have the following key-value pair:
"value": {
"label_ids": [relevant ids from the first json],
"description": "some text to render"
}
else the "value" is null.
I wish to compare the Set
values to the above mentioned recursive JSON's label_ids
and if one or more than one values in the label_ids
match with the Set
then change the checked
value to true
How does one accomplish this in Typescript/Angular?
I solved it by creating a Recursion Parsing Function which takes in the JSON Structure.
ngOnInit()
I call the service and pass it to the parseTree
functionSet
value
structure to render ititems
variablecomponent.ts:
parseTree(factors: TreeviewItem[]) {
factors.forEach(factor => {
// console.log(factor);
if (!isNil(factor.value)) {
let labels: number[] = factor.value['label_ids'];
labels.forEach(label => {
if(this.selected.findIndex(l => l == label) > -1) {
factor.value['highlighted'] = true;
factor.value['class'] = 'fas fa-flag';
}
});
}
if (!isNil(factor.children)) {
this.parseTree(factor.children);
}
});
this.items = factors;
}
here selections
is a Set
and within ngOnInit()
I set it a fixed value:
ngOnInit() {
this.selections.add(15);
this.items = this.parseTree(this.service.getDataQualityFactors());
}
Based on ngx-treeview
example I use the itemTemplate
in the code and add the Font-Awesome fonts next to the selections as follows:
component.html
<label class="form-check-label" *ngIf="item.value !== null && item.value['highlighted']">
<i class="{{item.value['class']}}" aria-hidden="true" title="Highlighted" [ngClass]="{'marked': item.checked}"></i>
</label>
and use the CSS classes to manipulate the color change of the font:
.fa-flag {
color: red;
}
.fa-flag.marked {
color: green;
}