Search code examples
angularjsng-class

Angular - ngClass being added to each clicked radio button (instead of ONLY clicked one)


In my angular app I'm using ng-repeat to generate several radio buttons, the ultimate goal is to add a choiceSelected class (ngClass colour styling) to the label of the clicked radio input. I can add the style to the clicked button, BUT that style is added to every other clicked radio button and I end up with 5 coloured labels. Can't understand why.

Here is the HTML code:

<div class="row" ng-repeat="obj in questionObject.choices">
  <div class="radio">
    <label class="choice" ng-class="{'choiceSelected': isChecked==$index}">
      <input type="radio" name="optradio" ng-model="isChecked" ng-value="$index" ng-click="selectAnswer($index,questionObject)">{{obj.body}}</label>
  </div>
</div>

Solution

  • <div class="row" ng-repeat="obj in questionObject.choices">
        <div class="radio">
            <label class="choice" ng-class="{'choiceSelected': isChecked==$index}">
             <input type="radio"
              name="optradio"
               /*********************************************/
               ng-model="isChecked"
               ng-value="$index"
               /*********************************************/
               ng-click="selectAnswer($index,questionObject)">{{obj.body}}
            </label>
        </div>
    </div>
    

    Look at the lines inside the comments, clearly tells that your value of the checkbox($index) is binding to the isChecked variable.

    By your, condition in ng-class isChecked==$index it is same for all the elements and so the class is applied for all radio buttons.

    if you can update the Json of questionObject , can give you alternative option.

    Assuming that questionObject contains the following json

     [{
        "body": "abc"
      }, {
        "body": "def"
      }, {
        "body": "aghi"
      } ]
    

    You can use the below code to make your result achieve

     <div class="row" ng-repeat="obj in questionObject track by $index" >
        <div class="radio" >
            <label class="choice" 
            ng-class="{'choiceSelected': isChecked==$index}">
              <input type="radio"
             name="optradio"
             ng-value="obj.body"
             ng-click="selectAnswer($index,obj)">
             {{obj.body}}
             </label>
    </div>
    

    The method selectAnswer should make your work simple. Use this

     $scope.selectAnswer=function(number,obj)
      {
        $scope.isChecked=number;
      }
    

    LIVE DEMO

    NOTE: In your code the selectAnswer method call in HTML passes the questionObject fully

    Update 1

    Reason for manually defining isChecked

    Angular looks for the the value of isChecked in the scope because you have used ng-class in the