Reputation: 322
I currently faced the issue of building the form on multiple choice questions. At this moment, the form for single choice works well, only left multiple choice questions. The goal I want to have is something like this:
{
"questions": [
// if multiple choices question
{
"question_id": 17,
"answer_ids": [81,82,83]
},
{
"question_id": 20,
"answer_ids": [101,102,104]
}
]
}
survey.ts
this.surveyForm = this.formBuilder.group({
questions: formBuilder.array([])
})
for (var i = 0; i < this.questions.length; i++) {
if(this.questions[i].question_type == '2') {
// get multiple
let question = formBuilder.group({
question_id: [this.questions[i].id, Validators.required],
answer_ids: formBuilder.array([])
});
this.surveyForm.controls['questions'].push(question);
// for (var j = 0; j < this.questions[i].answers.length; j++) {
// console.log(j);
// let answer = formBuilder.array(this.questions[i].answers)
// console.log(answer)
// this.questions[i].answers[j].push(new FormControl());
// this.surveyForm.controls['questions'].controls['answer_ids'].push(new FormControl('', [Validators.required]))
// };
console.log('m')
}
}
survey.html
<div *ngIf="surveyForm">
<form [formGroup]="surveyForm">
<div formArrayName="questions">
<div *ngFor="let question of questions; let i = index" [formGroupName]="i" padding-bottom>
<ion-row>
<ion-col col-2>
<h5>{{ i + 1 }}.</h5>
</ion-col>
<ion-col col-10>
<h5>{{ question.text }}</h5>
<p>{{ question.instruction }}</p>
<div *ngIf="question.question_type == 1; else multiple_choice">
<ng-template #multiple_choice>
<ion-list formArrayName="answer_ids">
<div *ngFor="let choice of question.answers; let i = index">
<ion-item>
<ion-label style="white-space: normal;">{{ choice.id }}</ion-label>
<ion-checkbox (ionChange)="onChange(choice.id, $event._checked)" value="choice.id"></ion-checkbox>
</ion-item>
</div>
</ion-list>
</ng-template>
</ion-col>
</ion-row>
</div>
</div>
</form>
</div>
What could be the best way that I can get the value id from each multiple choice checkbox to push into the array of specific question?
Upvotes: 3
Views: 6635
Reputation: 73357
This question is very similar to this: Angular 2 how to get the multiple checkbox value?
But since your is a bit more nested, we need to dig a bit deeper into the change event of the checkboxes.
From the template, we need in the change event pass choice.id, $event.checked
and i
. Please notice the naming convention in your template for the index. You are using the same name i
for both the top level iteration and the nested iteration, I have changed the nested iteration as j
, so:
<div *ngFor="let choice of question.answers; let j = index">
<ion-item>
<ion-label style="white-space: normal;">{{ choice.id }}</ion-label>
<ion-checkbox (ionChange)="onChange(choice.id, $event.checked, i)" value="choice.id">
</ion-checkbox>
</ion-item>
</div>
Please notice that in the change event we are passing i
, the top level iteration, where we iterate the questions.
So and over to the change function. Here it's similar to the answer in above linked question, but we need to dig deeper, since what we need to reach is the inner formArray.
Change event would look like this, where the path to our inner formarray is monstrous, as can be seen per the value of answers
below :)
onChange(id, isChecked, index) {
// nested formarray, which is inside nested formgroup, inside outer array
const answers = <FormArray>this.surveyForm.controls.questions.controls[index].controls.answer_ids
if(isChecked) {
answers.push(new FormControl(id))
} else {
let idx = answers.controls.findIndex(x => x.value == id)
answers.removeAt(idx)
}
}
This should do it! :)
Here's a DEMO!
Upvotes: 6