2017-06-01 1 views
1

Survey app checkbox photoIonic 2 Mehr Ankreuzfelder mit Formbuilder

ich zur Zeit das Problem des Aufbaus der Form auf Multiple-Choice-Fragen konfrontiert. In diesem Moment funktioniert die Form für Single-Choice gut, nur Multiple-Choice-Fragen übrig. Das Ziel, das ich haben will, ist so etwas wie dieses:

{ 
    "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> 

was der beste Weg sein könnte, dass ich den Wert bekommen kann ID aus jedem Multiple-Choice-Kontrollkästchen, um in das Array der spezifischen Frage zu schieben?

+0

So etwas ... https://Stackoverflow.com/a/43424244/6294072 – Alex

+0

@ AJT_82 Okay, es scheint ziemlich nah an der Struktur. Es scheint, dass es sich auf die Frage-ID für verschiedene Antwort-IDs beziehen muss. Irgendwie konnte ich keine Push-Daten mit diesem Code erhalten this.surveyForm.controls ['questions']. Controls ['answer_ids']. Push (neues FormControl ('' ', [Validators.required])) Bin ich falsch gemacht? – Yewness

+0

Könnten Sie einen Plünderer erstellen, mit dem ich basteln kann? :) – Alex

Antwort

3

Diese Frage ist sehr ähnlich wie diese: Angular 2 how to get the multiple checkbox value?

Aber da Ihr ein bisschen mehr verschachtelte ist, müssen wir ein wenig tiefer in das Änderungsereignis der Kontrollkästchen graben.

Von der Vorlage müssen wir in den Change Event choice.id, $event.checked und i übergeben. Bitte beachten Sie die Namenskonvention in Ihrer Vorlage für den Index. Sie verwenden den gleichen Namen i sowohl für die Top-Level-Iteration und die verschachtelte Iteration, ich habe die verschachtelte Iteration als j geändert, 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> 

Bitte bemerken, dass in dem Änderungsereignis wir i sind vorbei, die Iteration auf oberster Ebene, wo wir die Fragen iterieren.

So und wieder auf die Änderungsfunktion. Hier ist es ähnlich der Antwort in der oben verlinkten Frage, aber wir müssen tiefer graben, denn was wir erreichen müssen, ist die innere FormArray.

Change-Ereignis würde so aussehen, wo der Weg zu unserer inneren formarray monströs ist, gemäß dem Wert von answers unten :)

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) 
    } 
} 

Dies tut es gesehen werden kann, soll! :)

Hier ist ein DEMO!

+1

Danke!Das ist die Lösung, nach der ich suche. Es funktioniert gut zwischen meiner Single-Choice- und Multiple-Choice-Frage. – Yewness