4

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

4 Answers 4

8

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;
}
Sign up to request clarification or add additional context in comments.

4 Comments

if [checked]="topic in selectedTopics" doesnot work you can do [checked]="selectedTopics.indexof(topic) >= 0"
Unfortunately neither of these approaches worked. Either 'unexpected token 'in' ' or "unexpected method 'indexof'
@RobbieMills I have updated the answer please check it.
This is the approach I ended up using
3

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

1 Comment

@RobbieMills - Was there a problem with my answer? I see that you unmarked it after some part of my code was duplicated in another answer.
0

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.

1 Comment

But selectedTopics is anything that is checked... ? So I'm not sure how modifying the data will help. I've updated the question with additional details
0

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

1 Comment

That's great, but I'm not sure how it's relevant to my problem

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.