user308553
user308553

Reputation: 1250

nested ng-repeat, radio button validate

I have two nested ng-repeat that generate multiples questions and each question contain a bunch of radio buttons. I'm having trouble coming up with a efficient way to display the validation error message when no radio is selected for a certain question, and get all the selected choices when user hit select

    <ul>
      <li ng-repeat="question in questionModel.questionaire">{{question.question}}
      <span style = "color:red" ng-show = "!!!ANOTHER CONDITION HERE!!! && questionModel.submitClicked != false">Please choose an answer </span>

          <ul>

            <li ng-repeat="answer in question.answers">
              <input  type="radio"
                      ng-click="questionModel.handleChange(answer)"
                      value={{answer}}
                      name="radio_{{$parent.$index}}"
                      required>
              {{answer}}
            </li>
          </ul>

      </li>
    </ul>

How do you suggest I approach this? Use getElementById on ul then check all the children node? that sound really messy though, but it is easy, I can easily get all the button that was checked. Is there a better way to approach this for the validation error message?

If all radio buttons were under same question that would be easy, I can just ng-model on the radio button.

edit: addition info

controller:

  myApp.controller('questionController', function($scope, $http, toServer){

    $scope.questionModel = {
      questionaire: [],
      submitClicked: false,

      handleChange: function(ans){
        console.log(ans);
      },

      submit: function(){
        this.submitClicked = true;
        console.log(JSON.stringify(this.questionaire));
      }
    }

    toServer.get_All_Questions(function(response){
      $scope.questionModel.questionaire = response;
    });

  })

a service I created for ajax call:

//this service handle all the ajax call to server
myApp.factory('toServer', function($http){

  return {

    get_All_Questions: function(callback){
      var url = "/health1/server/questions";

      $http.get(url).success(function(response){
        response.forEach(function(item){
          item.answers = (item.answers != null) ? item.answers.split(",") : [];
          item.answered = false;
        });
        callback(response);
      }).error(function(response){
        console.log("error " + response)
      });
    }

  }

});

structure of the $scope.questionModel.questionaire (the response from server) is an array of json:

[{id: "1", question: "what's your name?", answers: ["tom", "mary"]},
{id: "2", question: "what's your age?", answers: [1, 2]}
]

Upvotes: 0

Views: 374

Answers (2)

Sajal
Sajal

Reputation: 4401

There was no property to recognize whether the question has been answered. So, i took the effort of creating such a property as isAnswered = true/false and initialized it to false on default.

angular.forEach($scope.questionModel.questionaire, function(ques) {
    ques.isAnswered = false;
    return ques;
});

When an answer is selected, the function handleChange sets isAnswered = true.

handleChange: function(ans, ques){
    ques.isAnswered = true;
    console.log(ques);
},

Finally, On submit click, the condition checks whether submit is clicked and if any question is unanswered, it will show the following message:

<span style = "color:red" 
   ng-show = "questionModel.submitClicked && !question.isAnswered">
   Please choose an answer 
</span>

Working Plunker

Upvotes: 1

Max
Max

Reputation: 1844

It's easy – use ng-model for your radio buttons:

<ul>
  <li ng-repeat="question in questionModel.questionaire" {{question.question}}
  <span style = "color:red" ng-show="!question.selectedAnswer && questionModel.submitClicked">Please choose an answer</span>
      <ul>
        <li ng-repeat="answer in question.answers">
          <input  type="radio"
                  ng-model="question.selectedAnswer"
                  ng-click="questionModel.handleChange(answer)"
                  value={{answer}}
                  name="radio_{{$parent.$index}}">
          {{answer}}
        </li>
      </ul>
  </li>
</ul>

Upvotes: 1

Related Questions