Created
January 6, 2017 11:42
-
-
Save webwizart/01a0a76ac3022567eb54573c0c989d8d to your computer and use it in GitHub Desktop.
Angular 2 - Dynamic Reactive form with Radio Inputs build with FormBuilder, FormGroup - !!! Working !!!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <form [formGroup]="reactiveForm" novalidate> | |
| <h2> Question {{question.Question.Order}} </h2> | |
| <h3> {{question.Question.QuestionText}}</h3> | |
| <p class="description"> {{question.Question.Description}} </p> | |
| <span *ngIf="question.Question.Type === 'SingleChoice'"> | |
| <span *ngFor="let answer of question.Question.PossibleAnswers; let i = index"> | |
| <br> | |
| <input #radio type="radio" [value]="answer.Id" formControlName="answer" [checked]="answer.IsAnswered" (click)="storeRadioSelection(answer.Id)" /> {{answer.Value}} | |
| <textarea *ngIf="answer.RequireJustification && radio.checked" | |
| name="justification" rows="3" cols="100" required placeholder="Please add your justification here" (blur)="storeJustification()"> {{answer.Justification}} | |
| </textarea> | |
| </span> | |
| </span> | |
| </form> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Component } from '@angular/core'; | |
| import { Input, Output, EventEmitter, OnChanges } from '@angular/core'; | |
| import { FormBuilder, FormGroup, FormArray } from '@angular/forms'; | |
| @Component({ | |
| moduleId: "module.id", | |
| selector: 'psq-question', | |
| templateUrl: 'question.component.html', | |
| styleUrls: ['question.component.css'] | |
| }) | |
| export class QuestionComponent implements OnChanges { | |
| @Input() question: any; | |
| @Input() questionsAndAnswersList: any; | |
| @Output() answeredQuestion = new EventEmitter; | |
| @Output() getAllQuestionsAndAnswers = new EventEmitter; | |
| @Output() updatePhase = new EventEmitter; | |
| reactiveForm: FormGroup; | |
| stepAndAnswer: any; | |
| selection = { | |
| options: { | |
| Id: '', | |
| Value: '', | |
| RequireJustification: false | |
| } | |
| }; | |
| answer = { | |
| PossibleAnswerId: '', | |
| Justification: '' | |
| }; | |
| answers = []; | |
| reviewMode = false; | |
| constructor(private fb: FormBuilder) { | |
| } | |
| ngOnChanges() { | |
| // Input properties are populated before ngOnInit() is called. | |
| // However, this assumes the parent property that feeds the input property is already populated when the child component is created | |
| // therefor use the OnChanges Lifecycle when you want to use it in your class. | |
| // If U only use it in the template you can use the regular ngOnInit | |
| if (this.question) { | |
| this.buildForm(); | |
| } | |
| } | |
| buildForm() { | |
| // use FormBuilder to build the model | |
| this.reactiveForm = this.fb.group({ | |
| }); | |
| // grab the FormGroup answers | |
| const fa = this.reactiveForm; | |
| // create a FormControl of each possible answer | |
| let fc = this.fb.control({ | |
| answer: this.question.Question.PossibleAnswers | |
| }); | |
| // add the new FormControl into the ansers FormArray | |
| fa.addControl('answer', fc); | |
| } | |
| storeRadioSelection(id) { | |
| console.log('id', id); | |
| this.answer.PossibleAnswerId = id; | |
| } | |
| storeJustification(justification) { | |
| console.log('justification', justification); | |
| this.answer.Justification = 'justification'; | |
| } | |
| // catch emmited child-component event | |
| getNextQuestion = (nextQuestion: any): void => { | |
| // get answer + selectedStep and sent to parent | |
| // construct the respone obj | |
| // get the selected answer | |
| this.answers = []; | |
| if (this.question.Question.Type === 'SingleChoice' | |
| && this.answer.PossibleAnswerId !== '') { | |
| this.answers.push(this.answer); | |
| } | |
| // TODO implment multiselection | |
| this.stepAndAnswer = { | |
| answeredQuestion: this.answers, | |
| nextQuestion: nextQuestion | |
| }; | |
| this.answeredQuestion.emit(this.stepAndAnswer); | |
| // cleanup | |
| this.answer = { | |
| PossibleAnswerId: '', | |
| Justification: '' | |
| }; | |
| this.stepAndAnswer = {}; | |
| }; | |
| getMultipleChoise = ($event, item) => { | |
| // implement | |
| }; | |
| // catch emmited child-component event | |
| getReviewMode = (mode: any) => { | |
| this.reviewMode = mode; | |
| this.getAllQuestions(); | |
| }; | |
| getAllQuestions = () => { | |
| this.getAllQuestionsAndAnswers.emit(this.reviewMode); | |
| }; | |
| revisitQuestions = (question) => { | |
| this.reviewMode = false; | |
| this.getNextQuestion(1); | |
| }; | |
| closePhase = (question) => { | |
| this.updatePhase.emit(question); | |
| }; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment