0

I have a table that is populated from an array coming from an API. The next thing I want to do is to add some checkboxes in a tab next to the table to filter data in the table. I'm adding the checkboxes dynamically because until the array comes from the API I don't know the filters (I know the category of the filters. ie Country or Language, but I don't know which countries or which languages will come in the array).

So, the problem is that I am trying to have a formArray to contain the checkboxes and I add to them programmatically as soon as I know what the values for the filters will be. But, when I try to click (just with my mouse) on the generated checkboxes I cannot. It doesn't check or uncheck.

However, if I just add the checkboxes without the formArray I can check and uncheck to my hearts content.

Here is my html for when I cannot check or uncheck (initially all of them are checked)

<form [formGroup]="languageForm">
    <div *ngIf='results && results.length'>
        <div class=" custom-control custom-checkbox mb-3" *ngFor="let item of languageForm.controls.filters.controls; let i = index" formArrayName="filters">
            <input class=" custom-control-input" [formControlName]="i" id="i" type="checkbox" />

            <label class=" custom-control-label" [for]="i">
                {{ f_languages[i].label }}
            </label>
        </div>
    </div>
</form>

Here is the html (for the one that does work)

<div *ngIf='results && results.length'>
    <div class=" custom-control custom-checkbox mb-3" *ngFor="let item of f_countries; let i = index">
        <input class=" custom-control-input" id="{{ item.value }}" type="checkbox" />

        <label class=" custom-control-label" for="{{ item.value }}">
            {{ item.value }}
        </label>
    </div>
</div>

Here is the TS for both (for the sake of the example I will make the filters static)

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
  f_countries = [
    {label: 'United States', value: 'US' },
    {label: 'United Kingdom', value: 'UK' },
    {label: 'Germany', value: 'DE' },
    {label: 'Philippines', value: 'PH' }
  ];

  f_languages = [
    {label: 'English', value: 'EN' },
    {label: 'German', value: 'DE' },
    {label: 'French', value: 'FR' },
    {label: 'Spanish', value: 'ES' }
  ];

//constructor omitted but nothing interesting there

ngOnInit() {
    // search form init and other things
    this.languagesForm = this.formBuilder.group({
      filters: new FormArray([])
    });
}

doSearch(): void {
    this.searchService.search(this.searchForm.get('country').value, this.searchForm.get('language').value)
        .subscribe(results => {
            this.results = results;
            this.slicedResults = this.results.slice(0, this.pageSize);

            //load the filters
            this.initializeFilters();
        });
}

initializeFilters(): void {
    //normally here the mapping from results to the filters 
    //but omitted since I said that for the example the filters are static

    this.f_languages.forEach((o, i) => {
      const control = new FormControl(true);
      (this.languagesForm.controls.filters as FormArray).push(control);
    });
  }

Thanks in advance for all the help, I'm sure it's something stupid that I just cannot see anymore after staring at it for so many hours.

EDIT -- I don't know exactly why this worked but it did. See below my final html which is now mysteriously clickable

<form [formGroup]="languagesForm">
    <div *ngIf='results && results.length'>
        <div class=" custom-control custom-checkbox mb-3" *ngFor="let item of languagesForm.controls.filters.controls; let i = index" formArrayName="filters">
            <input checked="checked" class=" custom-control-input" id="{{ i }}" [formControlName]="i" [value]="f_languages[i].value" type="checkbox" />

            <label class=" custom-control-label" [for]="i">
                {{ f_languages[i].label }}
            </label>
        </div>
    </div>
</form>

Apparently if it doesn't have id in the input and for in the label the thing is not un/checkable. Maybe someone will be able to explain why...

1
  • In the original example, the checkbox ID was being set to the string i. So there was no connection between the label and checkbox. Either the input must be placed inside the label, or there must be an ID set for the checkbox and the same ID in the for of the label. So your id="{{ i }}" works, as would [attr.id]="i". Cheers! Commented Oct 7, 2020 at 15:38

0

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.