Home > Enterprise >  Nested form validation in angular
Nested form validation in angular

Time:11-17

Stackblitz https://stackblitz.com/edit/angular-mh4cox?embed=1&file=src/app/app.component.html

How do I properly show error messages on nested forms? Validation works btw

I tried so many methods here without any luck.

I want it to show an error message on html using ngIF (... invalid && ... touched )

Constructor

    constructor(private fb: FormBuilder,private http:HttpClient,private requestService:RequestService) {
    this.myForm = this.fb.group({
      id:[""],
      areaOfInterest: new FormControl("",Validators.required),
      status: new FormControl("",Validators.required),
      startDate: new FormControl("",Validators.required),
      endDate: new FormControl("",Validators.required),
      description: new FormControl("",Validators.required),
      notes: new FormControl("",Validators.required),
      createdBy:"",
      updatedBy:"",
      resourceDTOS: this.fb.array([]),
    });
    console.log(this.myForm);
    this.getOneRequest(localStorage.getItem('requestId'));
  }

This is the nested resource which is a FormArray in this case

addNewResourceDTOS() {
    this.control = <FormArray>this.myForm.controls.resourceDTOS;
    this.control.push(
        this.fb.group({
          seniority: this.fb.control(null,Validators.required),
          skillDTOS: this.fb.array([this.fb.group({
            skill: '' //i dont validate it here
          })]),
          resourceNotes: this.fb.control(null,Validators.required),
        })
    );
  }

The array skillDTOS

addNewResourceSkill(control) {
    control.push(
        this.fb.group({
          skill: new FormControl("",Validators.required),
        }))
  }

This is how I'm validating some of my main form variables

  get description() {
    return this.myForm.get('description');
  }
  get notes() {

    return this.myForm.get('notes');
  }

Example html "notes"

<small *ngIf="notes.invalid && notes.touched" >Please enter notes!</small>

It looks something like this

 data = {
    areaOfInterest:"",
    notes:"",

    resourceDTOS: [
      {
        seniority: "",
        skillDTOS: [
          {
            skill: "",
          }
        ],
        resourceNotes:""
      }
    ]
  }

Is it possible to validate at least seniority/resourceNotes (or skill at best) as well?

CodePudding user response:

In your controller, you can define a new method that would check a particular field's validity based on its and its ancestor indeces. Here's an example for the skill field:

component.ts

  isSkillValid(resourceDTOSIndex: number, skillIndex: number): boolean {
    const resourceDTOSGroup = this.myForm.controls.resourceDTOS as FormGroup;
    const skillDTOSGroup =  resourceDTOSGroup.controls[resourceDTOSIndex] as FormGroup;
    const skillDTOS =  skillDTOSGroup.controls.skillDTOS as FormGroup;

    return skillDTOS.controls[skillIndex].valid;
  }; 

component.html

<input
  formControlName="skill"
  class="form-control"
  style="margin-right:5px;"
  type="text"
  placeholder="Enter skill"
  id="skill"
  name="skill"
  aria-label="button1"
  aria-describedby="button1"
/>

<div *ngIf="!isSkillValid(i, j)">
  The skill field has no valid value
</div>

P.S.

I would really suggest you refactor the component and split it into smaller pieces since it's already hard to read and manipulate over it.

  • Related