Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5 showing checkboxes as checked based on array

Tags:

angular

I have a set of dynamic checkboxes in an Angular form:

<div class="form-check" *ngFor="let topic of topics">
    <input class="form-check-input" (change)="onChange(f)" #f type="checkbox" [value]="topic.name" name="topicgroup">
    <label class="form-check-label" style="font-weight: normal">
        {{topic.name}}
    </label>
</div>

In my edit component, how do I set them as checked?

I have an array that holds all the options, and one which of the options are checked:

Topics: string[] = ['Topic1', 'Topic2', 'Topic3', 'Topic4', 'Topic5']; 
selectedTopics: string[] = ['Topic1', 'Topic2']; 

How do I reflect that on my html page?

Update: This is my onChange function:

onChange(f) {
if (this.selectedTopics.indexOf(f.value) == -1) {
  this.selectedTopics.push(f.value);
} else {
  this.selectedTopics.splice(this.selectedTopics.indexOf(f.value), 1);
}
like image 485
Robbie Mills Avatar asked Dec 24 '22 09:12

Robbie Mills


2 Answers

First, You are using topic.name as per your array it will be only topic.

Second, Add [checked] property to mark them as checked or unchecked as shown below.

<div class="form-check" *ngFor="let topic of topics">
    <input class="form-check-input" [checked]="topic in selectedTopics" (change)="onChange(topic)" #f type="checkbox" [value]="topic" name="topicgroup">
    <label class="form-check-label" style="font-weight: normal">
        {{topic}}
    </label>
</div> 

Third your function onChange(topic) will go as below

onChange(topic: string) {
  let index = this.selectedTopics.indexOf(topic);
  if (index == -1) {
    this.selectedTopics.push(value);
  } else {
    this.selectedTopics.splice(index, 1);
  }
}

UPDATE replace [checked]="topic in selectedTopics" with [checked] = isSelected(topic)

and in your controller add function

isSelected(topic){
    return selectedTopics.indexOf(topic) >= 0;
}
like image 72
Arpit Sancheti Avatar answered Jan 17 '23 05:01

Arpit Sancheti


As shown in this stackblitz, you can use [ngModel] and (ngModelChange) to bind your data to the input elements:

<div class="form-check" *ngFor="let topic of topics; let i=index">
  <input [ngModel]="isSelected(topic)" (ngModelChange)="onChange(topic, $event)" name="topicgroup_{{i}}" type="checkbox" class="form-check-input">
  <label class="form-check-label" style="font-weight: normal">
    {{topic}}
  </label>
</div>

with the methods isSelected and onChange defined in the component class:

topics: string[] = ['Topic1', 'Topic2', 'Topic3', 'Topic4', 'Topic5'];
selectedTopics: string[] = ['Topic1', 'Topic4'];

isSelected(value: string): boolean {
  return this.selectedTopics.indexOf(value) >= 0;
}

onChange(value: string, checked: boolean) {
  if (checked) {
    this.selectedTopics.push(value);
  } else {
    let index = this.selectedTopics.indexOf(value);
    this.selectedTopics.splice(index, 1);
  }
}

You mention in your question that these controls are to be included in a form. Each input element must therefore have a distinct name, which is achieved with the help of the index variable: name="topicgroup_{{i}}".

like image 40
ConnorsFan Avatar answered Jan 17 '23 05:01

ConnorsFan