I want to create dynamic checkbox based on object response,It should create multiple checkbox based on this response:
test.json
[
{
"header":{
"serviceId":"inquiry-service",
"productCode":"JPJXXX",
"transactionId":"cfad2ac7c16XXX"
},
"data":{
"items":[
{
"offenceType4":"",
"permSpeed":"110",
"actSpeed":"123",
"itemAttributes":{
"attribute5":"",
"attribute4":"VQ3XXX",
"attribute7":"14.21.00",
"attribute6":"2018-03-22",
"attribute1":"XXXXX",
"attribute3":"XXXXXX",
"attribute2":"XXXXXX"
},
"offenceLoc":"XXXXXX",
"itemNo":"1",
"summonDate":"2018-04-02",
"distCode":"XXXXXX",
"summonType":"2",
"hbtlOffndr":"N",
"itemAmount":15000,
"itemAttributesCount":7,
"summonAmt":"150.00",
"offenceType1":"48",
"offenceCode1":"XXXXXX",
"offenceType2":"",
"offenceCode2":"",
"offenceType3":"",
"category":"4",
"offenceCode3":"",
"offenceCode4":"",
"respCode":"XXXXXX"
},
{
"offenceType4":"",
"permSpeed":"110",
"actSpeed":"123",
"itemAttributes":{
"attribute5":"",
"attribute4":"XXXXXX",
"attribute7":"10.13.31",
"attribute6":"2018-06-16",
"attribute1":"XXXXXX",
"attribute3":"XXXXXX",
"attribute2":"XXXXXX"
},
"offenceLoc":"XXXXXX",
"itemNo":"2",
"summonDate":"2018-07-23",
"distCode":"XXXXXX",
"summonType":"2",
"hbtlOffndr":"N",
"itemAmount":15000,
"itemAttributesCount":7,
"summonAmt":"150.00",
"offenceType1":"48",
"offenceCode1":"XXXXXX",
"offenceType2":"",
"offenceCode2":"",
"offenceType3":"",
"category":"4",
"offenceCode3":"",
"offenceCode4":"",
"respCode":"XXXXXX"
}
],
"status":{
"code":"",
"message":""
},
"additionalProperties":{
"serviceFee":0,
"total":0,
"deliveryFee":0,
"foreignCardSurcharge":0,
"serviceFeeTax":0,
"subTotal":0,
"deliveryFeeTax":0
},
"metadata":{
"count":2
}
},
"status":{
"code":"200",
"message":"OK"
}
}
]
what I want is checkbox to be created based on data.items if items consist of 2 arrays, it should create 2 checkboxes.then selected checkboxes can be submit and it need header.transactionId, if I filter and only got data.items how could I add header.transactionId when submit.
I had created demo stackblitz and this is what I had tried:
Ts File
receivedSummons: SummonModel[];
selectedSummon: string;
form: FormGroup;
constructor(
private inquiryStore: InquiryStoreService,
private formBuilder: FormBuilder
) {
this.form = this.formBuilder.group({
receivedSummons: new FormArray([], minSelectedCheckboxes(1))
});
}
ngOnInit() {
this.getReceivedSummons();
}
getReceivedSummons() {
this.inquiryStore.summons$.subscribe(receivedSummons => {
this.receivedSummons = receivedSummons;
this.addCheckboxes();
})
}
addCheckboxes() {
this.receivedSummons.map((i) => {
const control = new FormControl;
(this.form.controls.receivedSummons as FormArray).push(control);
});
}
submitSelectedCheckboxes() {
this.selectedSummon = this.form.value.receivedSummons
.map((v, i) => (v ? this.receivedSummons[i] : null))
.filter(v => v !== null);
console.log(this.selectedSummon)
}
}
Html File
<form [formGroup]="form" (ngSubmit)="submitSelectedCheckboxes()">
<label formArrayName="receivedSummons" *ngFor="let summon of form.controls.receivedSummons.controls; let i = index">
<input type="checkbox" [formControlName]="i">
</label>
<div *ngIf="!form.valid">At least one order must be selected</div>
<br>
<button [disabled]="!form.valid">submit</button>
</form>
I could use some guidance and suggestion on how to solve this.
First of all when using FormBuilder try not to instantiate FormControl or FormArray directly. Instead use FormBuilder to do so.
this.form = this.formBuilder.group({
receivedSummons: this.formBuilder.array([])
});
As your response is an array you can get multiple receivedSummons which can contain multiple data.items. You need a different form structure to solve your issue.
Your addCheckboxes function might look like this.
addCheckboxes() {
this.formReceivedSummons.setValue([]);
this.receivedSummons.map(x => {
const group = this.formBuilder.group({
header: [x.header.transactionId],
items: this.formBuilder.array([], [minSelectedCheckboxes(1)])
});
x.data.items.map(y => {
(group.get('items') as FormArray).push(this.formBuilder.group({
name: [y.itemNo],
isChecked: ['']
}));
});
this.formReceivedSummons.push(group);
});
}
Also change the html file accordingly.
<form [formGroup]="form" (ngSubmit)="submitSelectedCheckboxes()">
<ng-container formArrayName="receivedSummons" *ngFor="let summon of formReceivedSummons.controls; let i = index">
<ng-container [formGroup]="summon">
<p>{{summon.value.header}}</p>
<ng-container formArrayName="items" *ngFor="let item of formReceivedSummonsItems(i).controls; let j = index">
<ng-container [formGroup]="item">
<input type="checkbox" formControlName="isChecked"> {{item.value.name}}
</ng-container>
</ng-container>
</ng-container>
<div *ngIf="!summon.valid">At least one order must be selected</div>
</ng-container>
<br>
<button [disabled]="!form.valid">submit</button>
</form>
Here 2 getters were used to get the receivedSummons and items FormArray
get formReceivedSummons() {
return this.form.get('receivedSummons') as FormArray;
}
formReceivedSummonsItems(i: number) {
return (this.formReceivedSummons.controls[i].get('items')) as FormArray;
}
Here you can find the full demo.
来源:https://stackoverflow.com/questions/57831605/display-checkbox-based-on-object-response-angular