Reputation: 649
I have some checkboxes whose value coming from json using ngFor. When I select those checkboxes and click submit, I need to capture the 'li' tag value and selected checkbox value in the form of array of object mentioned in output in code section. Here I am getting only 'li' tag value/text in the array but I am not getting how to push it into object along with selected checkbox value like output format.Here is the code below.
<div class="col-md-3" id="leftNavBar">
<ul *ngFor="let item of nestedjson">
<li class="parentNav">{{item.name}}</li>
<li class="childData">
<ul>
<li *ngFor="let child of item.value">{{child}}<span class="pull-right"><input type="checkbox"></span></li>
</ul>
</li>
</ul>
<div><button type="submit" (click)="getit()">submit</button></div>
</div>
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import Speech from 'speak-tts';
import { RxSpeechRecognitionService, resultList, } from '@kamiazya/ngx-speech-recognition';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
providers: [ RxSpeechRecognitionService ]
})
export class HomeComponent implements OnInit {
data:any;
nestedjson:any;
message = '';
test:any;
constructor(private formBuilder: FormBuilder,public service: RxSpeechRecognitionService) {
}
ngOnInit() {
this.nestedjson = [
{ name: "parent1", value: ["child11", "child12"] },
{ name: "parent2", value: ["child2"] },
{ name: "parent3", value: ["child3"] }
];
}
getit(){
const data = this.nestedjson;
let duplicatePushArray = [];
for(let i = 0; i < data.length ; i++){
if(duplicatePushArray.indexOf(data[i].name) === -1) {
duplicatePushArray.push(data[i].name);
} else {
console.log(`${data[i]} is already pushed into array`);
}
}
console.log('Final Array: ', duplicatePushArray)
/*output: [{"name":"parent1","value":["child11","child12"]},{"name":"parent2","value":["child2"]},{"name":"parent3","value":["child3"]}]*/
}
}
Upvotes: 0
Views: 1093
Reputation: 1357
You don't have anything happening when the checkbox is selected. I would recommending adding an onChange binding so that you can save all of your checked children to an array that you can reference when you click submit.
home.component.html
<li *ngFor="let child of item.value">{{child}}
<span class="pull-right">
<input type="checkbox" (change)="addtoChecked(child)">
</span>
</li>
home.component.ts
private checkedChildren = <string[]>[];
public addToChecked(child: string): void {
if(this.checkedChildren.indexOf(child) > -1){ // you can also pass in the $event from the html to this method to determine if it was checked or not
this.checkedChildren = this.checkedChildren.filter(c => c !== child);
} else {
this.checkedChildren.push(child);
}
}
getit(): void {
const output = <{name: string, value: string[]}[]>[];
this.checkedChildren.forEach((child) => {
const jsonData = this.nestedjson.find(j => j.value.indexOf(child) > -1);
if(!jsonData) {
// something went wrong
return;
}
const existingDataIndex = output.findIndex(o => o.name == jsonData.name);
if(existingDataIndex === -1){
output.push({ name: jsonData.name, value: [child]});
} else {
output[existingDataIndex].value.push(child);
}
});
console.log(output);
}
Upvotes: 1
Reputation: 10975
To achieve expected result, use below option of using reduce and checked flags for checkboxes
Add checked array to original Array to keep track of checked boxes
this.nestedjson.forEach(v => v.checked = Array(v.value.length).fill(false));
Updated array of checked values based on checked checkboxes
let duplicatePushArray = this.nestedjson.reduce((acc, v) => {
let temp = {name: v.name, value: []};
v.checked.forEach((val, i) => {
if(val){
temp.value.push(v.value[i]);
}
})
if(temp.value.length > 0){
acc.push(temp)
}
return acc
}, []);
Updated app.component.html and app.component.ts files below for reference
app.component.html:
<div class="col-md-3" id="leftNavBar">
<ul *ngFor="let item of nestedjson">
<li class="parentNav">{{item.name}}</li>
<li class="childData">
<ul>
<li *ngFor="let child of item.value; let i = index">{{child}}<span class="pull-right"><input type="checkbox" (change)="item.checked[i] = !item.checked[i]"></span></li>
</ul>
</li>
</ul>
<div><button type="submit" (click)="getit()">submit</button></div>
</div>
app.component.ts:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
data:any;
nestedjson:any;
message = '';
test:any;
constructor(private formBuilder: FormBuilder) {
}
ngOnInit() {
this.nestedjson = [
{ name: "parent1", value: ["child11", "child12"] },
{ name: "parent2", value: ["child2"] },
{ name: "parent3", value: ["child3"] }
];
this.nestedjson.forEach(v => v.checked = Array(v.value.length).fill(false));
}
getit(){
const data = this.nestedjson;
let duplicatePushArray = this.nestedjson.reduce((acc, v) => {
let temp = {name: v.name, value: []};
v.checked.forEach((val, i) => {
if(val){
temp.value.push(v.value[i]);
}
})
if(temp.value.length > 0){
acc.push(temp)
}
return acc
}, []);
console.log('Final Array: ', duplicatePushArray)
/*output: [{"name":"parent1","value":["child11","child12"]},{"name":"parent2","value":["child2"]},{"name":"parent3","value":["child3"]}]*/
}
}
Sample working code for reference - https://stackblitz.com/edit/angular-b9fmyz?file=src/app/app.component.html
Upvotes: 0