Skip to content

Instantly share code, notes, and snippets.

@webwizart
Created January 6, 2017 11:42
Show Gist options
  • Save webwizart/01a0a76ac3022567eb54573c0c989d8d to your computer and use it in GitHub Desktop.
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 !!!
<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>
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