5

I have a set of categories that is coming from a webservice: categories, and an array with selected categories: selectedCategories

To display all the checkboxes, I do:

<form [formGroup]="formGroup" (ngSubmit)="onSubmit()">
  <div class="row">
    <div *ngFor="let category of categories">
      <input type="checkbox" class="custom-control-input" [id]="category.id" formControlName="category"
             [checked]="categoriesSelected?.includes(category.id)">
      <label class="custom-control-label" [for]="category.id">{{ category.name | translate }}</label>
    </div>
  </div>
</form>

this works great.

Then I build my formGroup:

ngOnInit() {
    this.categoriesSelected = this.championships.map(championship => championship.category.id);
    this.formGroup = this.formBuilder.group({
      categories: this.formBuilder.array([{}])
    });
  }

Now, the output I need is just the ids of the selected categories.

I am a bit lost about linking the the formBuilder and the formGroup.

If I add formControlName="categories" in my template, in the input tag, all the data disappears.

How should I do it ?

1

2 Answers 2

5

You are close, you just need to pass categoriesSelected into this.formBuilder.array() and make some slight markup edits. In your component:

  constructor(private formBuilder: FormBuilder) {
    this.myGroup = this.formBuilder.group({
      myCategory: this.formBuilder.array(this.categoriesSelected)
    });
  }

You can use the index of the ngFor to access the separate categories array for labeling the checkboxes:

<form [formGroup]="myGroup">
    <div *ngFor="let category of myGroup.controls['myCategory'].controls; let i = index">
        <input type="checkbox" [formControl]="category">
    <label>{{ categories[i].name }}</label>
    </div>
  Selected: <strong>{{ myGroup.get('myCategory').value }}</strong>
</form>

Demo: https://stackblitz.com/edit/angular-vntktv

Sign up to request clarification or add additional context in comments.

Comments

1

Dynamic checkbox with Angular example

 musicForm: FormGroup;
 musicPreferences = [
 { id: 1, genre: 'Pop' },
 { id: 2, genre: 'Rock' },
 { id: 3, genre: 'Techno' },
 { id: 4, genre: 'Hiphop' }
 ];

 this.musicForm.get('selectAll').valueChanges.subscribe(bool => {
    this.musicForm
      .get('musicPreferences')
      .patchValue(Array(this.musicPreferences.length).fill(bool), { emitEvent: 
 false });
  });
 this.musicForm.get('musicPreferences').valueChanges.subscribe(val => {
  const allSelected = val.every(bool => bool);
  if (this.musicForm.get('selectAll').value !== allSelected) {
    this.musicForm.get('selectAll').patchValue(allSelected, { emitEvent: false 
 });
  }
});


  submit() {
// Filter out the unselected ids
const selectedPreferences = this.musicForm.value.musicPreferences
  .map((checked, index) => checked ? this.musicPreferences[index].id : null)
  .filter(value => value !== null);
// Do something with the result

}

   <form [formGroup]="musicForm" (ngSubmit)="submit()">
   <label>
    <input type="checkbox" formControlName="selectAll">
 Select/Deselect all
  </label>
  <label formArrayName="musicPreferences" *ngFor="let genre of 
   musicForm.controls['musicPreferences'].controls; let i = index">
  <input type="checkbox" [formControlName]="i">
  {{musicPreferences[i].genre}}
  </label>

  <button>submit</button>
  </form>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.