Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

253
Views
Angular - reactive forms with multipe checkboxes as a array touched validator issue

I'm trying to create a form where the user can select multiple colors and then submit the form.

Code

  colors: Array<any> = [
{ description: 'White', value: 'White' },
{ description: 'Black', value: 'Black' },
{ description: 'Blue', value: 'Blue' },
{ description: 'Green', value: 'Green' },
{ description: 'Yellow', value: 'Yellow' },
{ description: 'Red', value: 'Red' },
  ];

  constructor(
    private formBuilder: FormBuilder
  ) {
    this.fromInit();
  }

  ngOnInit(): void {}

  fromInit() {
    this.form = this.formBuilder.group({
      colors: this.formBuilder.array([], [Validators.required]),
    });
  }

  onCheckChange(event) {
    const formArray: FormArray = this.form.get(
      'colors'
    ) as FormArray;

    if (event.target.checked) {
      formArray.push(new FormControl(event.target.value));
    } else {
      let i: number = 0;

      formArray.controls.forEach((ctrl: FormControl) => {
        if (ctrl.value == event.target.value) {
          formArray.removeAt(i);
          return;
        }
        i++;
      });
    }
  }

  invalidColorsMessage() {
    if (this.form.controls['colors'].errors?.required)
      return "You must choose a color";
  }

HTML

      <div class="invalid-input-message"
       *ngIf="this.form.controls['colors'].touched &&
        this.form.controls['colors'].invalid">
    {{invalidColorsMessage()}}</div>

The issue that I encountered that property 'touched' of the this.form.controls['colors'] is always false. no matter if I select a few checkboxes or don't select anything the value of 'touched' is always false.

I don't really understand why it's always false when I check and uncheck the checkboxes.

the expected result is to show an error message whenever someone checks and unchecks the boxes and leaving all empty.

I would like to know why the value of this.form.controls['colors'].touched is always false no matter what. So I tried to search for the answer online but unfortunately with no success in finding the solution.

Here is a demo of the checkboxes : https://stackblitz.com/edit/angular-ivy-s8rc6j?file=src/app/app.component.html

thanks

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Update stackblitz:

  1. set isTouched = false; to global variable

  2. check *ngIf=="isTouched && this.form.controls['colors'].invalid"

  3. added this.isTouched = true; in onCheckChange(event) {}

This is Github closed issue

The touched property reflects whether a form control has been blurred, not changed.

The form touched would never return true because the blurred event only happened at input element.

You could change your code from:

<div class="invalid-input-message" *ngIf="this.form.controls['colors'].touched && this.form.controls['colors'].invalid">

To: (remove this.form.controls['colors'].touched condition)

<div class="invalid-input-message" *ngIf="this.form.controls['colors'].invalid">
about 4 years ago · Juan Pablo Isaza Report

0

You could use a custom validator, good thing, it is reusable! We attach it to the formarray and check the length of the array, if length is at least 1, we markAllAsTocuhed, therefore you can keep your touched in the template. So the function would look like:

export function validate(ctrls: FormArray): ValidationErrors | null {
  if (ctrls.value.length) {
    ctrls.markAllAsTouched();
    return null;
  }
  return { notValid: true };
}

You can put this in a service or somewhere where other components can import it if you want it to be reusable.

OK, so now let's attach this to the formarray:

fromInit() {
  this.form = this.formBuilder.group({
    colors: this.formBuilder.array([], { validators: validate }),
  });
}

And then in the template you check if error exist and if it's touched:

<div *ngIf="form.get('colors').hasError('notValid') && form.get('colors').touched">
  Please choose at least one
</div>

Your forked STACKBLITZ

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!