Reputation: 2580
I have a form control as such, that is generated via ngFor with an index.
<input formControlName='answerControl{{i}}' type="textbox" name="" value="{{ question.answer }}">
How can I add validation to this particular formControl if min length is not 4.
In my component I have:
this.answer_0 = new FormControl(this.questionsArr[0][2], Validators.minLength(4));
When I try:
<div *ngIf="answerControl{{i}}.valid">Error</div>
I get errors, this cannot be done.
Full TS Code:
@Component({
selector: 'app-fp-edit-pvq',
templateUrl: './fp-pvq.component.html',
animations: [
trigger('hideShow', [
state('hide', style({
opacity: 0,
height: 0
})),
state('show', style({
opacity: 1,
height: '*'
})),
transition('hide => show', animate('150ms ease-in')),
transition('show => hide', animate('150ms ease-out'))
])
]
})
export class FpPVQ implements OnInit {
constructor( private _pvqStepUp: PVQStepUpService, private _langToggle: ErrorToggleService ) { }
private questions: any;
private lang: string;
private counter: number = 0;
private checkedLimit: number = 5;
private updateMode: boolean = false;
private createMode: boolean = false;
private deadlinePassed: boolean = false;
private pvqForm:FormGroup;
private answer_0:FormControl;
private answer_1:FormControl;
private answer_2:FormControl;
private answer_3:FormControl;
private answer_4:FormControl;
private answer_5:FormControl;
private answer_6:FormControl;
private answer_7:FormControl;
private answer_8:FormControl;
private answer_9:FormControl;
private answer_10:FormControl;
private answer_11:FormControl;
private answer_12:FormControl;
private answer_13:FormControl;
private answer_14:FormControl;
private answer_15:FormControl;
private answer_16:FormControl;
private answer_17:FormControl;
private answer_18:FormControl;
private answer_19:FormControl;
private answerControlArr: Array<FormControl> = [];
private questionsArr: Array<any> = [];
ngOnInit() {
this.lang = document['locale'];
console.log('fpPVQ:: pvqStepUpData --> {}, ', this._pvqStepUp.data);
if(this._pvqStepUp.data != null){
this.questions = this._pvqStepUp.data.pvqs;
this.questions.forEach(object => {
this.questionsArr.push([object.question_EN, object.question_FR, object.answer]);
})
if(this._pvqStepUp.data.deadlinePassed)
this.deadlinePassed = true;
}
this.answer_0 = new FormControl(this.questionsArr[0][2], Validators.required);
this.answer_1 = new FormControl(this.questionsArr[1][2], Validators.required);
this.answer_2 = new FormControl(this.questionsArr[2][2], Validators.required);
this.answer_3 = new FormControl(this.questionsArr[3][2], Validators.required);
this.answer_4 = new FormControl(this.questionsArr[4][2], Validators.required);
this.answer_5 = new FormControl(this.questionsArr[5][2], Validators.required);
this.answer_6 = new FormControl(this.questionsArr[6][2], Validators.required);
this.answer_7 = new FormControl(this.questionsArr[7][2], Validators.required);
this.answer_8 = new FormControl(this.questionsArr[8][2], Validators.required);
this.answer_9 = new FormControl(this.questionsArr[9][2], Validators.required);
this.answer_10 = new FormControl(this.questionsArr[10][2], Validators.required);
this.answer_11 = new FormControl(this.questionsArr[11][2], Validators.required);
this.answer_12 = new FormControl(this.questionsArr[12][2], Validators.required);
this.answer_13 = new FormControl(this.questionsArr[13][2], Validators.required);
this.answer_14 = new FormControl(this.questionsArr[14][2], Validators.required);
this.answer_15 = new FormControl(this.questionsArr[15][2], Validators.required);
this.answer_16 = new FormControl(this.questionsArr[16][2], Validators.required);
this.answer_17 = new FormControl(this.questionsArr[17][2], Validators.required);
this.answer_18 = new FormControl(this.questionsArr[18][2], Validators.required);
this.answer_19 = new FormControl(this.questionsArr[19][2], Validators.required);
this.answerControlArr.push(this.answer_0);
this.answerControlArr.push(this.answer_1);
this.answerControlArr.push(this.answer_2);
this.answerControlArr.push(this.answer_3);
this.answerControlArr.push(this.answer_4);
this.answerControlArr.push(this.answer_5);
this.answerControlArr.push(this.answer_6);
this.answerControlArr.push(this.answer_7);
this.answerControlArr.push(this.answer_8);
this.answerControlArr.push(this.answer_9);
this.answerControlArr.push(this.answer_10);
this.answerControlArr.push(this.answer_11);
this.answerControlArr.push(this.answer_12);
this.answerControlArr.push(this.answer_13);
this.answerControlArr.push(this.answer_14);
this.answerControlArr.push(this.answer_15);
this.answerControlArr.push(this.answer_16);
this.answerControlArr.push(this.answer_17);
this.answerControlArr.push(this.answer_18);
this.answerControlArr.push(this.answer_19);
this.pvqForm = new FormGroup({
answerControl0: this.answer_0,
answerControl1: this.answer_1,
answerControl2: this.answer_2,
answerControl3: this.answer_3,
answerControl4: this.answer_4,
answerControl5: this.answer_5,
answerControl6: this.answer_6,
answerControl7: this.answer_7,
answerControl8: this.answer_8,
answerControl9: this.answer_9,
answerControl10: this.answer_10,
answerControl11: this.answer_11,
answerControl12: this.answer_12,
answerControl13: this.answer_13,
answerControl14: this.answer_14,
answerControl15: this.answer_15,
answerControl16: this.answer_16,
answerControl17: this.answer_17,
answerControl18: this.answer_18,
answerControl19: this.answer_19
});
this.questions.sort((a,b) => {
//This sorts all the entries
if(a.answer > b.answer) return -1;
});
//Determine if Update or Create
if(this._pvqStepUp.data.flow !== 'CREATE'){
this.createMode = true;
this.counter = 0;
} else {
this.updateMode = true;
this.counter = 5;
}
this._langToggle.getLanguage().subscribe(
lang => {
this.lang = lang.toString();
});
}
checkedState(event, checkBox){
if(event.target.checked === true){
if(this.counter < this.checkedLimit){
this.counter++;
} else {
event.target.checked = false;
}
} else if(this.counter > 0){
let index = event.target.name;
console.log('index is ', index);
console.log('Answer Control Array is ', this.answerControlArr);
console.log('Answer control is ', this.answerControlArr[index])
this.counter--;
}
}
onSubmit(pvqForm: any) {
console.log('4176-21 Submitted data --> {}', pvqForm);
console.log(pvqForm._value);
Object.keys(pvqForm._value).map((key) => {
console.log('4176-21 Object Key: ', key, ' Object Value: ', pvqForm._value[key]);
})
}
}
Full HTML:
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="container-generic bg-rbc-white">
<div class="row">
<div class="container-generic col-md-12">
<h1>Some Message about PVQS</h1>
<p>Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum.</p>
</div>
</div>
<form [formGroup]="pvqForm" (ngSubmit)="onSubmit(pvqForm)" novalidate>
<div *ngFor="let question of questions; let i = index" class="row container-generic">
<div class="col-md-8">
<div class="container-input-checkbox">
<label class="container-flex">
<input #checkBox class="pvq-create-checkbox" type="checkbox" name="{{i}}" (change)="checkedState($event, checkBox)" [checked]="question.answer">
<div class="pvq-create-label">
<div *ngIf="lang == 'en'">
<p>{{ question.question_EN }}</p>
</div>
<div *ngIf="lang == 'fr'">
<p>{{ question.question_FR }}</p>
</div>
</div>
</label>
<label [@hideShow]="checkBox.checked ? 'show' : 'hide'" >Answer
<input minlength=4 formControlName='answerControl{{i}}' type="textbox" name="{{i}}" value="{{ question.answer }}">
<div *ngIf="!{{i}}.valid" class="inline-validation critical">
<p>Error</p>
</div>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button [disabled]="pvqForm.invalid" class="button-primary" aria-label="Continue" type="submit">Continue</button>
<button *ngIf="deadlinePassed" class="button-secondary">Postpone</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
Upvotes: 1
Views: 2440
Reputation: 105547
You can use minlength
directive to add minlength
validator:
<input minlength=4 formControlName='answerControl{{i}}' type="textbox" name="" value="{{ question.answer }}">
Also you need to use the following syntax to target specific control in the validation div:
<div *ngIf="!pvqForm.controls['answerControl' + i].valid">Error here</div>
Here is the plunker that shows the solution and the relevant code:
TS
export class AppComponent {
questions = [
new FormControl('0'),
new FormControl('1'),
new FormControl('2')
];
pvqForm = new FormGroup({
answerControl0: this.questions[0],
answerControl1: this.questions[1],
answerControl2: this.questions[2],
});
HTML
<form [formGroup]="pvqForm" novalidate>
<div *ngFor="let question of questions; let i = index">
<input minlength=4 formControlName='answerControl{{i}}' type="text" name="{{i}}">
<div *ngIf="!pvqForm.controls['answerControl' + i].valid" class="inline-validation critical">
<p>Error</p>
</div>
</div>
</form>
You probably want to add check of the touched
state as well
pvqForm.controls['answerControl' + i].touched
so errors are only shown when there was some interaction with a control:
<div *ngIf="!pvqForm.controls['answerControl' + i].valid && pvqForm.controls['answerControl' + i].touched" ...>
You can also set the validator manually in the component class:
pvqForm.answerControl0.setValidators(Validators.minLength(4))
Upvotes: 2
Reputation: 6900
Your template should look like this
<input minlength="4" formControlName='answerControl{{i}}' type="textbox" name="" value="{{ question.answer }}">
and in your .ts file
this.answer_0 = new FormControl(this.questionsArr[0][2], Validators.required);
also try adding novalidate
to the form element <form.... novalidate>
Upvotes: 0