1

I am working on an Angular 12 application. It has a table with multiple rows populated dynamically. Each row has four columns. The third column has radioButton Yes No as shown.

  • Desired Output: Example, if the table has three rows and I want to select Yes Radio button in first row, No in second and I don't want to select any in third row, it should be allowed.

enter image description here

  • Actual Output: It is letting me select only one row with either Yes or No.

My html to be populated dynamically : marks-input-component.html

<ng-container *ngIf="!!markForm" [formGroup]="markForm">
  <ng-container *ngIf="inputType === inputEnum.RADIO_BUTTON">
    <fieldset>
      <ng-container *ngFor="let item of options">
        <div class="float-left">
          <input type="radio" [formControl]="oneInputControl" id="{{ item.markId }}-{{ item.id }}" [value]="item.id">
          <label for="{{ item.markId }}-{{ item.id }}">&nbsp;{{ item.option }}</label>
        </div>
      </ng-container>
    </fieldset>
  </ng-container>
<br>

My dynamic ts file : marks-input-component.ts

export class MarksInputComponent implements OnInit{
  @Input() inputType: string;
  @Input() markId: number;
  @Input() markForm: FormGroup;

  options: MarkOption[];
  
    ngOnInit(): void {
    super.ngOnInit();
    this.initOptions();
    this.connectListeners();
  }
  
    private connectListeners() {
    this.onOneInputChange();
  }

  private onOneInputChange() {
    this.oneInputControl.valueChanges.pipe(
      takeUntil(this.destroyed$),
      tap((value) => {
        const id = parseInt(value);
        if (id) {
          const option = this.options.find(v => v.id === id);
          option ? this.markForm.controls.mark.patchValue(option.mark) : this.markForm.controls.mark.patchValue(undefined);
        } else {
          this.oneInputControl.patchValue(-1, { onlySelf: true, emitEvent: false });
          this.markForm.controls.mark.patchValue(undefined);
        }
      })
    ).subscribe();
  }
  
  get responses() {
    return this.markForm.controls.responses as FormArray;
  }

  get oneInputControl() {
    const f = this.responses.controls[0] as FormGroup;
    return f.controls.markId as FormControl;
  }
  }

The html page: marks-component.html

<ng-container *ngFor="let markForm of allMarkForms.controls">
    <ng-container *ngFor="let markResponse of manualMarks; let rowNum = index">
        <ng-container *ngIf="markForm.controls.markId.value === markResponse.markId">
            <tr id="manual-mark-response-row-{{ rowNum }}" }}">
                <td id="mark-id-{{ rowNum }}">{{ markResponse.markIdText }}</td>
                <td id="mark-text-{{ rowNum }}">{{ markResponse.markText }}</td>
                <td id="mark-mark_description-{{ rowNum }}">
                        <!-- marks input component -->
                    <app-dynamic-input
                          [inputType]="markResponse.inputType"
                          [markId]="markResponse.markId"
                          [markForm]="markForm"></app-dynamic-input>
                    
                </td>
                 <td id="mark-mark-{{ rowNum }}">
                    <ng-container *ngIf="markResponse.inputType === inputEnum.RADIO_BUTTON">
                          {{ markForm.controls.mark.value }}
                     </ng-container>
           
                 </td>
            </tr>
        </ng-container>
    </ng-container>
</ng-container>
0

2 Answers 2

2

You're assigning the same FormControl to each input, so they will act as a single input group. In reality, you need a unique FormControl for each yes / no pair.

Here's a simple example of a form with three yes / no questions

export class OneComponent {
  myFormGroup = new FormGroup({
    q1: new FormControl(),
    q2: new FormControl(),
    q3: new FormControl(),
  });

  get allControlNames() {
    return Object.keys(this.myFormGroup.controls);
  }
}
<form [formGroup]="myFormGroup">
  <ng-container *ngFor="let controlName of allControlNames">
    <label>
      <input type="radio" [value]="true" [formControlName]="controlName" />
      <span>YES</span>
    </label>
    <label>
      <input type="radio" [value]="false" [formControlName]="controlName" />
      <span>NO</span>
    </label>
    <br />
  </ng-container>
</form>

Use formControlName="" to select a specific FormControl from the encapsulating FormGroup.

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

Comments

0

In the input type radio, I was missing unique name field for each yes / no pair. Adding name="{{ item.markId }}-test" this worked for me.

<input type="radio" name="{{ item.markId }}-test" [formControl]="oneInputControl" id="{{ item.markId }}-{{ item.id }}" [value]="item.id">

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.