2

I am designing a feedback page where, There are multiple questions are being asked and all the questions have same multiple choice answers. So I have designed like below.

options: string[] = ['Excellent', 'Fair', 'Good', 'Poor'];

  questions: any = [
    {
      question: "How would you rate A",
      answer: this.options,
      radioSelected: ""
    },
    {
      question: "How would you rate B",
      answer: this.options,
      radioSelected: ""
    },
    {
      question: "How would you rate C",
      answer: this.options,
      radioSelected: ""
    },
    {
      question: "How would you rate D",
      answer: this.options,
      radioSelected: ""
    },
    {
      question: "How would you rate E",
      answer: this.options,
      radioSelected: ""
    }
  ];
<div *ngFor="let q of questions; index as i">
        <label id="example-radio-group-label">{{q.question}}</label>
        <div class="row">
            <div class="form-check" *ngFor="let option of q.answer">
                <div class="col-md-3">
                    <input class="form-check-input" id="{{option}}" [value]="option" type="radio" name="options"
                        [(ngModel)]="q.radioSelected">
                    <label class="form-check-label" for="{{option}}">
                        {{option}}
                    </label>
                </div>
            </div>
        </div>
        <hr>
    </div>

The code is displaying fine in the UI. But When I click on the radio button for any question, Only first question's options are getting selected. I am new to angular, Kindly help me how to solve this.

Pradyskumar
  • 296
  • 1
  • 3
  • 15

3 Answers3

1

You are missing unique name attribute on radio. The Name should be unique for one set of Options.

In your use case where radio buttons are generated dynamically you can use index of loop to set name like this -

 <div *ngFor="let q of questions; let  questionIndex=index">
                    <label id="example-radio-group-label">{{q.question}}</label>
                    <div class="row">
                        <div class="form-check" *ngFor="let option of q.answer; let answerIndex=index">
                            <div class="col-md-3">
                                <input class="form-check-input" [value]="option" type="radio" name="options{{questionIndex}}{{answerIndex}}"
                                    [(ngModel)]="q.radioSelected">
                                <label class="form-check-label">
                                    {{option}}
                                </label>
                            </div>
                        </div>
                    </div>
                    <hr>
                </div>

Please check working example here.

Similar question here and here.

Hope this will help you !!

Santosh Shinde
  • 6,045
  • 7
  • 44
  • 68
  • I tried this answer, didn't work. `q.radioSelected` is updating only first question – Pradyskumar Feb 22 '20 at 16:41
  • @Pradyskumar Please check working example here, https://stackblitz.com/edit/radio-name?file=src/app/app.component.html – Santosh Shinde Feb 22 '20 at 17:04
  • @shindesan2012, Thanks, I tried question index instead of answer index. It is working fine – Pradyskumar Feb 22 '20 at 17:04
  • 1
    "You are missing unique name attribute on radio". @SantoshShinde, not really, the input HAS the `name` attribute set, however, yes, as you mentioned later, it should be unique for each section. Another thing I'd suggest is to avoid the `for` and `id` for this case. IMHO, it's a desnecessary complexity, just putting the `input` inside the `label` is enough, as mentioned in [seanplwong's answer](https://stackoverflow.com/questions/60354188/how-to-keep-track-of-index-in-double-ngfor-loop-in-angular#60354267). – developer033 Feb 22 '20 at 17:07
  • @developer033 Yes we have to avoid the `for` and `id` in `label` and `input`, I just tried make his code get work and will get some hints. Also I have mention same thing in my answers with links of other answers. – Santosh Shinde Feb 22 '20 at 17:14
  • @developer033 when I use `inpun` inside `label` radio button is not displaying in UI. Only label is visible. – Pradyskumar Feb 22 '20 at 17:16
0

You are probably rendering something like

<div>Question 1</div>
<div>
  <div>
    <input id="Excellent" ...>
    <label for="Excellent">Ex</label>
  </div>
</div>

<div>Question 2</div>
<div>
  <div>
    <input id="Excellent" ...>
    <label for="Excellent">Ex</label><!-- This is pointing to the first input -->
  </div>
</div>

First, do not duplicate id. And you could avoid the complexity of <label for=""> by just wrapping input inside label:

<label><input />Excellent</label>
seanplwong
  • 1,051
  • 5
  • 14
-1

you can assign the index for the answers loop to a different name and concatenate that index with the name value. try this:

<div *ngFor="let q of questions; let  i=index">
    <label id="example-radio-group-label">{{q.question}}</label>
    <div class="row">
        <div class="form-check" *ngFor="let option of q.answer; let answerIndex=index">
            <div class="col-md-3">
                <input class="form-check-input" id="{{option}}" [value]="option" type="radio" name="options{{answerIndex}}"
                    [(ngModel)]="q.radioSelected">
                <label class="form-check-label" for="{{option}}">
                    {{option}}
                </label>
            </div>
        </div>
    </div>
    <hr>
</div>
Mike Araya
  • 155
  • 1
  • 11