lundi 18 janvier 2016

Select atleast one checkbox in angularjs from each table

I have to validate a questionnaire before submitting it. The question-answer tables are generated dynamically from json file. Before submitting the questionnaire, at least one answer should be checked from each question. For an unattempted question, it should validate as 'Please select atleast one checkbox/answer'

My problem: I am able to validate ' Atleast once checkbox selection' for one question, but I not able to validate for all questions.
It validates if any one of the checkbox is selected on whole page. I want each question should have atleast one answer selected.
My code shows validation error[Please select atleast one checkbox/answer'] even for the selected answer question. 
It should show validation error only on the questions which are not attempted[i.e. questions whose atleast one answer is also not selected]

I have gone through multiple post on angularJs group check box validation, but not able to satisfy my problem.

Can any one please help me out!

Thanks in advance!





// quest_answer.json
[
    {
      "id": "0",
      "header": "Fruits",
      "question": "Which fruit do you like?", 
      "answer": [
        {"aid": 0, "value" : "Apple", "isChecked" : false},
        {"aid": 1, "value" : "Banana", "isChecked" : false},
        {"aid": 2, "value" : "Strawberry", "isChecked" : false},
        {"aid": 3, "value" : "Grapes", "isChecked" : false},
        {"aid": 4, "value" : "Mango", "isChecked" : false}  
      ],
      "notes":""
    },
    {
      "id": "1",
      "header": "Vegetables",
      "question": "Which vegetable do you like?", 
      "answer": [
        {"aid": 0, "value" : "Potato", "isChecked" : false},
        {"aid": 1, "value" : "Spinach", "isChecked" : false},
        {"aid": 2, "value" : "Cabbage", "isChecked" : false},
        {"aid": 3, "value" : "Brinjal", "isChecked" : false}
      ],
      "notes":""
    },
    {
      "id": "2",
      "header": "Color",
      "question": "Which color do you like?", 
      "answer": [
        {"aid": 0, "value" : "Red", "isChecked" : false},
        {"aid": 1, "value" : "Orange", "isChecked" : false},
        {"aid": 2, "value" : "Green", "isChecked" : false},
        {"aid": 3, "value" : "Blue", "isChecked" : false},
        {"aid": 4, "value" : "Pink", "isChecked" : false}
      ],
      "notes":""
    },
    {
      "id": "3",
      "header": "Animal",
      "question": "Which animal do you like?", 
      "answer": [
        {"aid": 0, "value" : "Monkey", "isChecked" : false},
        {"aid": 1, "value" : "Dog", "isChecked" : false},
        {"aid": 2, "value" : "Cat", "isChecked" : false},
        {"aid": 3, "value" : "Cow", "isChecked" : false}       
      ],
      "notes":""
    }
]

// questionnaire.html



<div ng-init="init()">
<div class="module">
  <div class="module-head">
    <center><h3> <b>Evaluation</b> </h3></center>
  </div>
    <center>
  <div class="module-body" >
      <div> Questionnaire About the Project/Initiative</div>
      <hr>
      <form name="qForm" ng-submit="evaluate_Report(qForm.$valid)" novalidate>
      <hr>
        <div>Question Set</div>
      <hr>
      <div ng-repeat="myQuestion in questionnaire">
      <table id="personal_table" class="table table-striped table-bordered table-hover" style="width:70%">                      
                      <tbody>                         
                           <hr>
                          <center><thead>{{myQuestion.header}}</thead></center>
                        <tr style="width:100%">                                  
                            <th rowspan="{{questionnaire[$index].answer.length+1}}" scope="rowgroup"style="width:50%">{{myQuestion.question}}</th>                               
                            <th  style="width:2%">:</th> 
                            <th  style="width:48%">Tick all that apply  <div ng-show="qForm.$submitted && qForm.ansCheck.$error.required">Please select atleast one checkbox</div>                                                                      </th> 
                        </tr>
                         <tr ng-repeat="answer in questionnaire[$index].answer">
                         <td><input type="checkbox" name="ansCheck" ng-model="answer.isChecked" ng-change="selectAnswer($parent.$index, $index, answer)" ng-required="!anySelected($parent.$index,answer)" >

                             </td><td> {{answer.value}} </td>                                 
                          </tr>                                         
                         <tr style="width:100%">                                  
                            <td style="width:50%" id="q2">Special Notes</td>                             
                            <td style="width:1%">:</td> 
                            <td style="width:49%"><input type=text ng-model="personal_info_notes">{{myQuestion.notes}} </td>                            
                         </tr>                           
                      </tbody>                    
        </table>          
      </div>
       <center><button type=submit id="btn_evaluate">Evaluate Report</button></center>
       <hr>         
      <hr>  

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



//questionnaire.js


app.controller('questionnaire', ['$scope','$http','$sce','$routeParams',function($scope, $http, $sce, $routeParams) {

    $scope.questionAttempted = []; // an array containing question ids which are attempted
    $scope.questionAnswerAttempted=[];//an array containing answers which are checked    

    $scope.init=function()
    {
        $http.get('quest_answer.json').then(function(questionnaireData){      
            $scope.questionnaire = questionnaireData.data; 
         });                    
    }    


    $scope.selectAnswer = function(qIndex, aIndex, selectedAnswer)
    {         
        var selectedIndex = $scope.questionAnswerAttempted.indexOf(selectedAnswer.value);  
        var selectedQuestion= $scope.questionAttempted.indexOf(qIndex);  

        if(selectedIndex == -1 && selectedAnswer.isChecked){        
            $scope.questionAnswerAttempted.push(selectedAnswer.value);          
            if(selectedQuestion == -1){
                $scope.questionAttempted.push(qIndex);                
            }
        }else if(!selectedAnswer.isChecked && selectedIndex != -1){
            $scope.questionAnswerAttempted.splice(selectedIndex,1);           
             var  aLength = $scope.questionnaire[qIndex].answer.length;      
                //Remove the question id from the questionAttempted array only if none of the answers are checked.
            if(aLength >0){
                   for(a=0;a<aLength;a++){
                       if($scope.questionnaire[qIndex].answer[a].isChecked){
                            console.log("Atleast one answer is checked for this question. So no of questions attempted remains same:" + $scope.questionAttempted.length);  
                           flag = false;
                           break;                           
                       }else{
                           flag = true;                                                    
                       }
                   }
                if(flag){
                    $scope.questionAttempted.splice(selectedQuestion,1);
                          console.log("No answers are checked for this question. So removing it");   
                          console.log("No of questions attempted after splicing:" + $scope.questionAttempted.length);
                }

            }            
        }        
    }

    // For ng-required attribute of checkboxes. Should return 'true' for attempted question and 'false' for unattempted question
    $scope.anySelected = function(qIndex,answer){
        var qaLength =$scope.questionAttempted.length;
          if(qaLength > 0){
              for(var q = 0; q < qaLength ; q++){                  
                  if($scope.questionAttempted[q] == qIndex ){  
                       return true;
                  }else{
                      return false;
                  }
              }             
          }else{
              return false;
          }     
    }

      $scope.evaluate_Report = function(isValid)
      {
          if(isValid){
              alert('Form is valid');
          }else{
              alert('Form is Incomplete');
          }
    }

}]);


    app.controller('questionnaire', ['$scope','$http','$sce','$routeParams',function($scope, $http, $sce, $routeParams) {

        $scope.questionAttempted = []; // an array containing question ids which are attempted
        $scope.questionAnswerAttempted=[];//an array containing answers which are checked    
        
        $scope.init=function()
        {
            $http.get('quest_answer.json').then(function(questionnaireData){      
                $scope.questionnaire = questionnaireData.data; 
             });                    
        }    
       
        
        $scope.selectAnswer = function(qIndex, aIndex, selectedAnswer)
        {         
            var selectedIndex = $scope.questionAnswerAttempted.indexOf(selectedAnswer.value);  
            var selectedQuestion= $scope.questionAttempted.indexOf(qIndex);  
           
            if(selectedIndex == -1 && selectedAnswer.isChecked){                
                $scope.questionAnswerAttempted.push(selectedAnswer.value);          
                if(selectedQuestion == -1){
                    $scope.questionAttempted.push(qIndex);                
                }
            }else if(!selectedAnswer.isChecked && selectedIndex != -1){
                $scope.questionAnswerAttempted.splice(selectedIndex,1);           
                 var  aLength = $scope.questionnaire[qIndex].answer.length;      
                                //Remove the question id from the questionAttempted array only if none of the answers are checked.
                if(aLength >0){
                       for(a=0;a<aLength;a++){
                           if($scope.questionnaire[qIndex].answer[a].isChecked){
                                console.log("Atleast one answer is checked for this question. So no of questions attempted remains same:" + $scope.questionAttempted.length);  
                               flag = false;
                               break;                           
                           }else{
                               flag = true;                                                    
                           }
                       }
                    if(flag){
                        $scope.questionAttempted.splice(selectedQuestion,1);
                              console.log("No answers are checked for this question. So removing it");   
                              console.log("No of questions attempted after splicing:" + $scope.questionAttempted.length);
                    }
                    
                }            
            }        
        }
        
        // For ng-required attribute of checkboxes. Should return 'true' for attempted question and 'false' for unattempted question
        $scope.anySelected = function(qIndex,answer){
            var qaLength =$scope.questionAttempted.length;
              if(qaLength > 0){
                  for(var q = 0; q < qaLength ; q++){                  
                      if($scope.questionAttempted[q] == qIndex ){  
                           return true;
                      }else{
                          return false;
                      }
                  }             
              }else{
                  return false;
              }     
        }
        
          $scope.evaluate_Report = function(isValid)
          {
              if(isValid){
                  alert('Form is valid');
              }else{
                  alert('Form is Incomplete');
              }
        }
         
    }]);
    .module {
        
    /*  box-shadow: 0 0 3px rgba(0,0,0,.1); */
        border-color: #e9e9e9;
        margin-bottom: 50px;
        background-color: #fff;
       /* border-radius: 4px;*/
    /*    -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);*/
        box-shadow: 0 1px 1px rgba(0,0,0,.05);     
        -webkit-border-radius: 3px;
        -moz-border-radius: 3px;
        border-radius: 3px;
        border: 1px solid #ccc;
        border-bottom-color: #bbb;
        -webkit-box-shadow: 0 0 1px rgba(0,0,0,0.2);
        -moz-box-shadow: 0 0 1px rgba(0,0,0,0.2);
        box-shadow: 0 0 1px rgba(0,0,0,0.2);
    }


    .module-head {      
        color: #767676;
        background-color: #f6f6f6;
        border-color: #e9e9e9;
        padding: 10px 15px;
        border-bottom: 1px solid transparent;
        border-top-right-radius: 3px;
        border-top-left-radius: 3px;            
    }

    .module-head h3 {
        font-size: 20px;
        line-height: 20px;
        height: 20px;
        margin: 0;
        font-weight: bold;
    }

    .module-body {
        padding: 15px;
        width:1350px;
        margin-right: auto;
        margin-left: auto;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <!-- title and meta -->
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta http-equiv='REFRESH' content='43200'/>
    <meta name="Pragma" content="no-cache;">
    <title>Web</title>

    <link type="text/css" rel="stylesheet" href="bootstrap/css/bootstrap.min.css">  
      <link type="text/css" rel="stylesheet" href="css/theme.css"> 
      </head>
    <body ng-app="app">
      
    <div ng-init="init()">
    <div class="module">
      <div class="module-head">
        <center><h3> <b>Evaluation</b> </h3></center>
      </div>
        <center>
      <div class="module-body" >
          <div> Questionnaire About the Project/Initiative</div>
          <hr>
          <form name="qForm" ng-submit="evaluate_Report(qForm.$valid)" novalidate>
          <hr>
            <div>Question Set</div>
          <hr>
          <div ng-repeat="myQuestion in questionnaire">
          <table id="personal_table" class="table table-striped table-bordered table-hover" style="width:70%">                      
                          <tbody>                         
                               <hr>
                              <center><thead>{{myQuestion.header}}</thead></center>
                            <tr style="width:100%">                                  
                                <th rowspan="{{questionnaire[$index].answer.length+1}}" scope="rowgroup"style="width:50%">{{myQuestion.question}}</th>                                       
                                <th  style="width:2%">:</th> 
                                <th  style="width:48%">Tick all that apply  <div ng-show="qForm.$submitted && qForm.ansCheck.$error.required">Please select atleast one checkbox</div>                                                                      </th> 
                            </tr>
                             <tr ng-repeat="answer in questionnaire[$index].answer">
                             <td><input type="checkbox" name="ansCheck" ng-model="answer.isChecked" ng-change="selectAnswer($parent.$index, $index, answer)" ng-required="!anySelected($parent.$index,answer)" >
                                                                               
                                 </td><td> {{answer.value}} </td>                                 
                              </tr>                                         
                             <tr style="width:100%">                                  
                                <td style="width:50%" id="q2">Special Notes</td>                                     
                                <td style="width:1%">:</td> 
                                <td style="width:49%"><input type=text ng-model="personal_info_notes">{{myQuestion.notes}} </td>                                                      
                             </tr>                           
                          </tbody>                    
            </table>          
          </div>
           <center><button type=submit id="btn_evaluate">Evaluate Report</button></center>
           <hr>           
          <hr>  
          
      </div>
    </div>
    </div>
        </center>
      
      <script src="http://ift.tt/1xDNnh9"></script>
    <script src= "scripts/core/angular/angular.js"></script>
    <script src= "scripts/core/angular/angular-route.js"></script>
    <script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>  
      <script src="scripts/controllers/questionnaire.js" type="text/javascript"></script>
      </body>
    </html>





Aucun commentaire:

Enregistrer un commentaire