Thinker
Thinker

Reputation: 5366

angular2 creating and populating radio button group with ngFor

I am basically iterating over a JSON object array and trying to create radio buttons pre-selected with values:

<div *ngFor="let task of tasks">
    <p>
        <mdl-textfield label="What task" type="text" formControlName="what_task" floating-label [ngModel]="task.what_task"></mdl-textfield>
    </p>

    <p>
        How often do you perform?<br/>
        <mdl-radio value="Daily" formControlName="how_often" mdl-ripple [(ngModel)]="task.how_often">Daily once</mdl-radio>
        <mdl-radio value="Weekly" formControlName="how_often" mdl-ripple [(ngModel)]="task.how_often">Weekly once</mdl-radio>
    </p><br>

</div>

Consider I have two tasks, one has value of how_often set to 'Daily' and the second has it set to 'Weekly'. Two sets of radio buttons are created but both get value 'Weekly' i.e. of the second task.

What am I doing wrong in this case? What is the correct way to generate radio button pairs with ngFor?

UPDATE:

My entire template:

<mdl-expansion-panel-group>
    <mdl-expansion-panel *ngFor="let task of tasks">
        <mdl-expansion-panel-header>
            <mdl-expansion-panel-header-list-content><h6>{{task.what_task}}</h6></mdl-expansion-panel-header-list-content>
        </mdl-expansion-panel-header>
        <mdl-expansion-panel-content>
            <mdl-expansion-panel-body>

                <form [formGroup]="form">

                    <!-- What task -->
                    <p>
                        <mdl-textfield label="What task" type="text" formControlName="what_task" floating-label [ngModel]="task.what_task"></mdl-textfield>
                    </p>


                    <!-- How often -->
                    <p>
                        How often do you perform?<br/>
                        <mdl-radio value="Daily" formControlName="how_often" mdl-ripple >Daily once</mdl-radio>
                        <mdl-radio value="Weekly" formControlName="how_often" mdl-ripple >Weekly once</mdl-radio>
                    </p><br>

                    <!-- How important -->
                    <p>
                        How important it is?<br/>
                        <mdl-radio value="Extremely" formControlName="how_important" mdl-ripple [ngModel]="task.how_important">Extremely important</mdl-radio>
                        <mdl-radio value="Rather" formControlName="how_important" mdl-ripple [ngModel]="task.how_important">Rather important</mdl-radio>
                    </p><br>

                    <!-- Why -->
                    <p>
                        <mdl-textfield rows="3" label="Why do you need to perform" type="text" [ngModel]="task.why_perform" formControlName="why_perform"  floating-label></mdl-textfield>
                    </p>

                    <!-- Why important -->
                    <p>
                        <mdl-textfield rows="3" label="Why is it important" type="text" [ngModel]="task.why_important" formControlName="why_important" floating-label></mdl-textfield>
                    </p>

                    <!-- Possible improvement -->
                    <p>
                        <mdl-textfield rows="3" label="What improvement you can think of" type="text" 
                        [ngModel]="task.possible_improvement" formControlName="possible_improvement" floating-label></mdl-textfield>
                    </p>


                    <!-- Existing solutions -->
                    <p>
                        <mdl-textfield rows="3" label="What are the tools/solutions that you use" type="text" [ngModel]="task.existing_solutions" formControlName="existing_solutions" floating-label></mdl-textfield>
                    </p>

                    <!-- How important improvement -->
                    <p>
                        How important is the improvement?<br/>
                        <mdl-radio value="Extremely" formControlName="how_important_improvement" mdl-ripple [ngModel]="task.how_important_improvement">Extremely important</mdl-radio>
                        <mdl-radio value="Rather" formControlName="how_important_improvement" mdl-ripple [ngModel]="task.how_important_improvement">Rather important</mdl-radio>
                    </p><br>

                    <!-- Advantages of improvement -->
                    <p>
                        How important is the improvement?<br/>
                        <mdl-radio value="Saves money" formControlName="advantages_of_improvement" mdl-ripple [ngModel]="task.advantages_of_improvement">Saves money</mdl-radio>
                        <mdl-radio value="Saves time" formControlName="advantages_of_improvement" mdl-ripple [ngModel]="task.advantages_of_improvement">Saves time</mdl-radio>
                        <mdl-radio value="Saves efforts" formControlName="advantages_of_improvement" mdl-ripple [ngModel]="task.advantages_of_improvement">Saves rfforts</mdl-radio>

                    </p><br>


                    <p>
                        <button mdl-button (click)="updateTask(task, task.id)" [disabled]="!form.valid" mdl-button-type="raised" mdl-ripple mdl-colored="primary">Submit</button>
                    </p>
                </form>

                <div style="color: red;" *ngIf="errorMessage">
                    <h4>{{errorMessage}}</h4>
                </div>

                <div style="color: green;" *ngIf="successMessage">
                    <h4>{{successMessage}}</h4>
                </div>

            </mdl-expansion-panel-body>
        </mdl-expansion-panel-content>
    </mdl-expansion-panel>
</mdl-expansion-panel-group>

and in component I have:

    this.form = fb.group({
      'what_task': this.what_task,
      'how_often': this.how_often,
      'how_important': this.how_important,
      'why_perform': this.why_perform,
      'why_important': this.why_important,
      'possible_improvement': this.possible_improvement,
      'existing_solutions': this.existing_solutions,
      'how_important_improvement': this.how_important_improvement,
      'advantages_of_improvement': this.advantages_of_improvement,

    });
  }

  ngOnInit() {
    this.getTasks();
  }

  public updateTask(task, taskId) {
    console.log(task, taskId);

    this.steps=task.steps; 


    this.task.what_task=this.form.value.what_task
    this.task.how_often=this.form.value.how_often
    this.task.how_important=this.form.value.how_important
    this.task.why_perform=this.form.value.why_perform
    this.task.why_important=this.form.value.why_important
    this.task.possible_improvement=this.form.value.possible_improvement
    this.task.existing_solutions=this.form.value.existing_solutions
    this.task.how_important_improvement=this.form.value.how_important_improvement
    this.task.advantages_of_improvement=this.form.value.advantages_of_improvement

    this.taskService.updateTask(this.task, taskId).subscribe(
      task => {
        this.task = task,

        this.errorMessage=null;
        this.successMessage='Task updated successfully!'
      },
      error =>  {
        this.errorMessage = <any>error;
        this.successMessage=null;

      })


  }

Upvotes: 0

Views: 256

Answers (1)

ChrisG
ChrisG

Reputation: 2948

The reason for this is they are all (all 4 of them) referencing the same formControl as seen here: formControlName="how_often".

By making a FormArray, which matches each task, you will achieve the desired result.

taskform.component.ts

createFormGroup() {
  return this.fb.group({
      'what_task': this.what_task,
      'how_often': this.how_often,
      'how_important': this.how_important,
      'why_perform': this.why_perform,
      'why_important': this.why_important,
      'possible_improvement': this.possible_improvement,
      'existing_solutions': this.existing_solutions,
      'how_important_improvement': this.how_important_improvement,
      'advantages_of_improvement': this.advantages_of_improvement,
  });
}

ngOnInit() {
  this.getTasks();

  this.formArray = new FormArray([]);
  for(const task of this.tasks) {
    this.formArray.push(this.createFormGroup());
  }
}

taskform.component.html

<mdl-expansion-panel *ngFor="let task of tasks; let i = index">
    <form [formGroup]="formArray.at(i)">

In the template I only highlighted the major changes. Other than those lines, your template should be able to stay as is.

I have created a sample plunkr here: https://plnkr.co/edit/qIZiBPAjJeYG73c3vmhb?p=preview

Upvotes: 1

Related Questions