0

I have a form with only radio buttons, the form must be validated before submission (user must select something). After user selects a radio button some styling should apply using ngclass. I have two problems:
1. For some reason the last option is selected by default.
2. I am not able to get form validation attributes. The data is not refreshed when I select stuff on it.

plunkr

JS:

app.controller('MainCtrl', function($scope) {

  $scope.questionObject = [{
    "body": "abc"
  }, {
    "body": "def"
  }, {
    "body": "aghi"
  } ]
  $scope.selectAnswer=function(number,obj)
  {
    $scope.isChecked=number;
}
});

HTML:

  <div class="form-group" ng-form="form">
    <div class="col-lg-8 col-lg-offset-2 col-sm-12">
      <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-click="selectAnswer($index,questionObject.correct_answer)"
                  ng-model="radioInput">{{obj.body}}
          </label>
        </div>
      </div>
    </div>
  </div>
  <pre>
   dirty:{{form.$dirty}}
   pristine:{{form.$pristine}}
  </pre>

EDIT This is the form output. Never gets updated

   {
  "$error": {},
  "$name": "form",
  "$dirty": false,
  "$pristine": true,
  "$valid": true,
  "$invalid": false,
  "$submitted": false
}

2 Answers 2

2

Try like this. look for the ng-model and ng-required attributes for radio button.

<div name="myForm" novalidate ng-form>
    <div class="col-lg-8 col-lg-offset-2 col-sm-12">
      <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-click="selectAnswer($index,questionObject.correct_answer)" ng-model="data.option" ng-value="obj.body" ng-required="data.option == ''">{{obj.body}}
      </label>

        </div>
      </div>
    </div>
  </div>

  <pre>
     dirty:{{myForm.$dirty}}
     pristine:{{myForm.$pristine}}
     $valid:{{myForm.$valid}}
     $invalid:{{myForm.$invalid}}
  </pre>

Plunker :https://plnkr.co/edit/crpV5QnSGdSv6rUBnTnR?p=preview

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

5 Comments

This seem to change $invalid status only when the user clicks on the last option. But besides that $pristine changes on the first selection.
@undroid updated the plunker and answer to show the valid and invalid status of the form. Let me know in case you have any query.
Yes now your example works. I cant make this work on my side, will have to dig deeper. Care to explain the logic behind your ng-model manipulation?
ng-model is the property on the scope, this value is set to the ng-value of radio button when the particular radio button is selected. I have set the ng-required attribute to true if the ng-model property is blank. if the ng-model is blank that means form is invalid and when the user select any radio button the value of mg-model will be set and form becomes valid.
This fixed it for me. Incredible that we have to hack it like that :)
0

With radio buttons one is going to be selected by default. You can use checkboxes instead and control them with angularjs so that only one is selected.

To do this give each question object a selected property which will initially be false:

  $scope.questionObject = [{
    "body": "abc",
    "selected": false
  }, {
    "body": "def",
    "selected": false
  }, {
    "body": "aghi",
    "selected": false
  }];

Then when the user selects a checkbox your selectAnswer function can be used to ensure only one checkbox is ever selected:

  $scope.selectAnswer = function(obj) {
    angular.forEach($scope.questionObject, function(val) {
      if (obj !== val) {
        val.selected = false;
      }
    });
  };

Plunker: https://plnkr.co/edit/0TBDHJEjDpiIjmhd3AqT?p=preview

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.