4

I have the following code that dynamically adds a form group containing a title and two radio buttons to create a condition, effectively providing its title and whether or not it's an acceptable condition:

export enum Acceptability {
  ACCEPTABLE,
  INACCEPTABLE
}

export interface Condition {
  title: string;
  acceptability: Acceptability;
}

export class AddCondition implements OnInit {

  form: FormGroup;
  ACCEPTABILITY = Acceptability;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    // build the form
    this.form = this.fb.group({
      conditions: this.fb.array([])
    });

  }

  get conditions(): FormArray {
    return this.form.get('conditions') as FormArray;
  }

  addCondition() {
    this.conditions.push(this.fb.group({
      title: ['', Validators.required],
      acceptability: ['', Validators.required]
    }));
  }
}
<div formArrayName="conditions">
  <div *ngFor="let condition of conditions.controls; let i=index" [formGroupName]="i">
    <input class="form-control" formControlName="title" type="text" placeholder="title">
    <div class="custom-control custom-radio custom-control-inline">
      <input type="radio" id="acceptable" formControlName="acceptability" name="acceptability" class="custom-control-input" [value]="ACCEPTABILITY.ACCEPTABLE">
      <label class="custom-control-label" for="acceptable">Acceptable</label>
    </div>
    <div class="custom-control custom-radio custom-control-inline">
      <input type="radio" id="inacceptable" formControlName="acceptability" name="acceptability" class="custom-control-input" [value]="ACCEPTABILITY.INACCEPTABLE">
      <label class="custom-control-label" for="inacceptable">Inacceptable</label>
    </div>
  </div>
  <button type="button" class="btn btn-outline-dark btn-block" (click)="addCondition()">
          <i class="fa fa-plus fa-lg mr-3"></i>ADD A NEW CONDITION</button>
</div>

The problem is that when clicking the ADD A NEW CONDITION button, and the new form group appears, every time I select any radio button in the group array, the corresponding radio button of the first array item in the group is the one that gets selected.

4
  • FYI it's un acceptable Commented Jan 14, 2018 at 16:54
  • LOL! True; the problem is I renamed everything from French, effectively overlooking that :) Commented Jan 14, 2018 at 16:55
  • are there any errors in the console? sounds like something is broken Commented Jan 14, 2018 at 17:17
  • Absolutely not. Commented Jan 14, 2018 at 17:21

2 Answers 2

7

What you need to consider when looping through an array group is the id and name you assign to each one. You currently have your input id and name getting set to the same value in each loop.

You would need to use the i variable you have available to make the id and name for each input a dynamic value, like below:

<div [formGroup]="form">
  <div *ngIf="conditions" formArrayName="conditions">

    <div *ngFor="let condition of conditions.controls; let i=index" [formGroupName]="i">

      <input class="form-control" formControlName="title" type="text" placeholder="title">

      <div class="custom-control custom-radio custom-control-inline">
        <input type="radio" id="{{ 'acceptable' + i}}" formControlName="acceptability"
            class="custom-control-input" [value]="ACCEPTABILITY.ACCEPTABLE">
        <label class="custom-control-label" for="{{ 'acceptable' + i}}">Acceptable</label>
      </div>

      <div class="custom-control custom-radio custom-control-inline">
        <input type="radio" id="{{ 'unacceptable' + i}}" formControlName="acceptability"
            class="custom-control-input" [value]="ACCEPTABILITY.INACCEPTABLE">
        <label class="custom-control-label" for="{{ 'unacceptable' + i}}">Unacceptable</label>
      </div>

    </div>

    <button type="button" class="btn btn-outline-dark btn-block" (click)="addCondition()">
            <i class="fa fa-plus fa-lg mr-3"></i>ADD A NEW CONDITION</button>
  </div>
</div>

<div>
  <pre>{{ form.value | json }}</pre>
</div>

Notice the string interpolation for the name and id attributes. Same goes for the for attribute in the labels.

You may have to play around with this to get is exactly where it needs to be. (I didn't test it thoroughly)

Hope this helps.

Sign up to request clarification or add additional context in comments.

10 Comments

Thank you, but this then produces the following error: If you define both a name and a formControlName attribute on your radio button, their values must match. Ex: <input type="radio" formControlName="food" name="food">
But then of course, if I go ahead and change formControlName to match it, then I get the error that the control does not exist; which is normal since when I push the new group, I push it with the name acceptability only.
Have you tried it without setting the name attribute at all by removing it?
Okay, let me try a few things. I will update the answer when I have something. Sorry about the back and forth!
Indeed; I guess removing name and not having formControlName dynamic was the one permutation I did not try. Thank you :)
|
0

I seems that you missed this line id="{{ 'unacceptable' + i}}" for id & label both.

Comments

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.