Robbie Mills
Robbie Mills

Reputation: 2945

Angular 5 showing checkboxes as checked based on array

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);
}

Upvotes: 4

Views: 7798

Answers (4)

Arpit Sancheti
Arpit Sancheti

Reputation: 248

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;
}

Upvotes: 8

Martin Parenteau
Martin Parenteau

Reputation: 73761

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}}".

Upvotes: 3

Chellappan வ
Chellappan வ

Reputation: 27471

Angular varible are case sensitive check this working example:https://stackblitz.com/edit/angular-uwekdb?file=app%2Fapp.component.ts

Upvotes: 0

Sajeetharan
Sajeetharan

Reputation: 222722

You need to change your datastructure as array of objects with value and checked property

selectedTopics: any[] = [ {'value':'Topic1','checked':false}, {'value':'Topic2','checked':true}]; 

whenever checkbox is checked/unchecked you can update the checked property to get the value.

Upvotes: 0

Related Questions