So everything works fine with normal FormGroup but when it comes to FormArray it doesn't focus the invalid input.
My form initialization is below
initForm() {
this.parentForm= this.fb.group({
childFormArray: this.fb.array([this.createchildForm()])
});
}
after this, I initialize formarray like below
createChildForm(data?: any): FormGroup {
var childForm = this.fb.group({
name: [data?.name? data?.name: '']
});
childForm .valueChanges.subscribe(value => {
var fieldWithValue = Object.keys(value).filter(key => value[key] == '');
fieldWithValue.forEach(conName => {
childForm .get(conName)?.addValidators([Validators.required]);
});
});
return childForm ;
}
My method to set errors after clicking submit (requirement);
assignError(){
this.parentForm.controls.childFormArray.value.forEach((v: any, index: number) => {
var array = this.parentForm.controls.childFormArrayas FormArray;
var item = array.at(index);
var emptyItems = Object.keys(v).filter(key => v[key] == '');
emptyItems.forEach(ele => {
if (ele != "section") {
item.get(ele)?.updateValueAndValidity({ emitEvent: false });
}
});
});
}
and after this I have made my validator which will check for invalid input and focus it.
import { Directive, HostListener, ElementRef } from '@angular/core';
@Directive({
selector: '[focusInvalidInput]'
})
export class FormDirective {
constructor(private el: ElementRef) { }
@HostListener('submit')
onFormSubmit() {
const invalidControl = this.el.nativeElement.querySelector('.ng-invalid');
if (invalidControl) {
invalidControl.focus();
}
}
}
after this I have used its selector in my corresponding form
focusInvalidInput (ngSubmit)="saveDetails()"
and inside submit method I call my error adding method which is
saveDetails(){
assignError();
}
After doing all this I am able to focus invalid input but somehow its not working for formarray.
and when I console invalidControl its prints all the invalid input which should not happen maybe bcz there are many invalid input and whome should it focus so I tried using .first() method but it gives error saying first is not a method
The actual reason was focus doesn't work on div and my input which were using formArray's controls were wrapped inside a div which is
<div id="resp-table-body" *ngFor="let item of getParentFormControls(); let i = index"
[formGroupName]="i">
<div class="table-body-cell">
<input type="text" class="form-control no_shadow_input" id="name"
placeholder="Enter Here" formControlName="name" autocomplete="off">
<span *ngIf="item.get('name')?.hasError('required')"
class="text-danger">
Name is required
</span>
</div>
</div>
So all I had to change is add input.ng-invalid in my directive
const invalidControl = this.el.nativeElement.querySelector('input.ng-invalid');
Now everything is working fine