AngularJS: loop through radio button groups

All we need is an easy explanation of the problem, so here it is.

I am making an AngularJs survey application.
I want to show tasks one by one. And every task can have one or multiple questions with radio button answers. And I want to save question+answer pair in the new array.

If I want to show only one question per task than I was able to get answer values from radio buttons and push then into answer array. But as I have multiple questions and multiple radio button groups per page, I can’t find a way to get the selected radio buttons values and push them into the answers array. I have read that ng-model can solve this, but I couldn’t figure how.

This is what I have so far: https://jsfiddle.net/8qfom9th

<div ng-app="surveyApp" ng-controller="surveyCtrl">
<div ng-repeat="questionSet in questionSet">
    <div ng-if="question_index == $index">


          <div ng-repeat="onePageQuestions in questionSet.onePageQuestions">

            <div ng-repeat="question in onePageQuestions.question">
              {{question.description}}

              <form action="">

              <div ng-repeat="options in question.options">
                  <input type="radio" name="gender" ng-model="question.random" ng-value="options.answer"> {{options.answer}}
              </div>

            </form>

            </div>

          </div>

    </div>
</div>
<hr>
<button ng-click="next(); submitAnswers()">Next</button>

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

It’s actually pretty simple buddy.

You can get the value of the selected button by using the checked property. Since only one radio button can be selected from a group, you would be able to get the value of the selected one easily using this property in an if loop within the javascript.

  • Since you have given the options of the radio buttons a name already, i.e., gender. You can simply get all the options elements, using the following:

    var options = document.getElementsByName('gender');
    var option_value; //to get the selected value
    
  • The next step is to loop through all the buttons and check which of those is selected.. To loop through them use a for loop as follows: for (var i = 0; i < options.length; i++) {...}

    To check if it is selected or not, use the checked attribute as follows:

    if (options[i].checked) {
        option_value = options[i].value;
    }
    

I’m not sure what you intend to do with those values, hence I have assumed that you need to display those and to do that just create another element, like a <div> and give it an ID. And then just add the selected option value to that element. Should be something like this:

HTML: <div id="selected">The selected options are:</div>

JS:document.getElementById('selected').innerHTML += "<br>" + option_value;

Updated your fiddle.

Or if you want to check it right here,
here is the updated code:

var app = angular.module('surveyApp', []);

app.controller('surveyCtrl', function($scope) {
  $scope.questionSet = [{

      onePageQuestions: [{

        question: [{
            description: 'question#1?',

            options: [{
              answer: 'answer#1'
            }, {
              answer: 'answer#2'
            }, {
              answer: 'answer#3'
            }]
          },

          {

            description: 'question#2?',
            options: [{
              answer: 'answer#4'
            }, {
              answer: 'answer#5'
            }, {
              answer: 'answer#6'
            }]
          }
        ]

      }]


    },


    {

      onePageQuestions: [{

        question: [{
          description: 'question#3?',

          options: [{
            answer: 'answer#7'
          }, {
            answer: 'answer#8'
          }, {
            answer: 'answer#9'
          }]
        }]

      }]

    }




  ];

  $scope.question_index = 0;

  $scope.next = function() {
    if ($scope.question_index >= $scope.questionSet.length - 1) {
      $scope.question_index = 0;
    } else {
      $scope.question_index++;
    }

  };

  $scope.submitAnswers = function() {

    var options = document.getElementsByName('gender');
    var option_value;
    for (var i = 0; i < options.length; i++) {
      if (options[i].checked) {
        option_value = options[i].value;
        document.getElementById('selected').innerHTML += "<br>" + option_value;
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="surveyApp" ng-controller="surveyCtrl">
  <div ng-repeat="questionSet in questionSet">
    <div ng-if="question_index == $index">


      <div ng-repeat="onePageQuestions in questionSet.onePageQuestions">

        <div ng-repeat="question in onePageQuestions.question">
          {{question.description}}

          <form action="">

            <div ng-repeat="options in question.options">
              <input type="radio" name="gender" ng-model="question.random" ng-value="options.answer"> {{options.answer}}
            </div>

          </form>

        </div>

      </div>

    </div>
  </div>
  <hr>
  <button ng-click="next(); submitAnswers()">Next</button>
  <hr>
  <div id="selected">The selected options are:
  </div>
</div>

Method 2

Use parent.answer for ng-model for dynamic radio button.
And for your use case I have added one saveAnswers functions to manipulate and save users answers.

Below is the code for your use case demo, run it and see updated questionSet in console.

var app = angular.module('surveyApp', []);

app.controller('surveyCtrl', function($scope) {
  $scope.answer = '';
  $scope.saveAnswers = function(description, options) {
    $scope.questionSet.map(function(value, key) {
      value.onePageQuestions.map(function(item, index) {
        item.question.map(function(question, count) {
          if (question.description === description.description) {
            question.answer = options;
          }
        })

      })
    })
  }
  $scope.questionSet = [{
      onePageQuestions: [{
        question: [{
            description: 'question#1?',
            answer: '',
            options: [{
              answer: 'answer#1'
            }, {
              answer: 'answer#2'
            }, {
              answer: 'answer#3'
            }]
          },

          {

            description: 'question#2?',
            answer: '',
            options: [{
              answer: 'answer#4'
            }, {
              answer: 'answer#5'
            }, {
              answer: 'answer#6'
            }]
          }
        ]

      }]


    },


    {

      onePageQuestions: [{

        question: [{
          description: 'question#3?',
          answer: '',

          options: [{
            answer: 'answer#7'
          }, {
            answer: 'answer#8'
          }, {
            answer: 'answer#9'
          }]
        }]

      }]

    }




  ];

  $scope.question_index = 0;

  $scope.next = function() {

    if ($scope.question_index >= $scope.questionSet.length - 1) {
      $scope.question_index = 0;
    } else {
      $scope.question_index++;
    }

  };

  $scope.submitAnswers = function() {
    console.log($scope.questionSet)
  }



});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<div ng-app="surveyApp" ng-controller="surveyCtrl">
  <div ng-repeat="questionSet in questionSet">
    <div ng-if="question_index == $index">


      <div ng-repeat="onePageQuestions in questionSet.onePageQuestions">

        <div ng-repeat="question in onePageQuestions.question">
          {{question.description}}

          <form action="">

            <div ng-repeat="options in question.options">
              <input ng-change="saveAnswers(question,options.answer)" type="radio" name="gender" ng-model="$parent.answer" ng-value="options.answer"> {{options.answer}}
            </div>
          </form>

        </div>

      </div>

    </div>
  </div>
  <hr>
  <button ng-click="next()">Next</button>
  <button ng-click="submitAnswers()"> Submit</button>

Hope this will help you!

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply