最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ShowHide elements dynamically in AngularJs - Stack Overflow

programmeradmin10浏览0评论

I'm currently experimenting with Angular and I have an issue, I have a set of questions from my API, some of them rely on other ones to be checked as yes when its a radio button question and will have a value in the property called ReliesOnID.

Once I check yes, the question which relies on the current one being checked needs to show.

I e from a jQuery background so I would do a function passing in the reliesonid as that will be the question number and do something like $('#question' + reliesonid').show().

How can I make the radio buttons show the other question when I click yes as they are in a repeat? Been stuck on this for ages so help is greatly appreciated. Here is my code below:

<div id="question{{question.Number}}" ng-repeat="question in questions" ng-class="question.ReliesOnID == null ? 'here' : 'hidden'">
    <div ng-if="question.QuestionTypeID == 3" >
        <div class="row">
            <div class="col-xs-12">
                <h5>{{question.Question}}</h5>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-2">
                <div class="col-xs-4"></div>
                <div class="col-xs-8">
                    <input type="radio" value="yes" name="{{question.Number}}"  /><label>Yes</label>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-2">
                <div class="col-xs-4"></div>
                <div class="col-xs-8">
                    <input type="radio" value="no" name="{{question.Number}}" /><label>No</label>
                </div>
            </div>
        </div>
    </div>
    <div ng-if="question.QuestionTypeID == 1">
        <div class="row">
            <div class="col-xs-12">
                <h5>{{question.Question}}</h5>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-4">
                <input type="text" class="form-control" />
            </div>
        </div>
    </div>
</div>


EDIT: Data structure is:

{
    "Active": true,
    "Comments": false,
    "DecimalPlaces": 0,
    "F": false,
    "FP": false,
    "Grouped": null,
    "ID": 20500,
    "Length": false,
    "MP": true,
    "Multiline": false,
    "Number": 45,
    "NumericOnly": false,
    "Optional": false,
    "Question": "How long ago was the treatment?",
    "QuestionID": 45,
    "QuestionSectionID": 2,
    "QuestionTypeID": 2,
    "QuestionnaireID": 298,
    "ReliesOnAnswer": true,
    "ReliesOnID": 44,
    "Weight": false
}

I'm currently experimenting with Angular and I have an issue, I have a set of questions from my API, some of them rely on other ones to be checked as yes when its a radio button question and will have a value in the property called ReliesOnID.

Once I check yes, the question which relies on the current one being checked needs to show.

I e from a jQuery background so I would do a function passing in the reliesonid as that will be the question number and do something like $('#question' + reliesonid').show().

How can I make the radio buttons show the other question when I click yes as they are in a repeat? Been stuck on this for ages so help is greatly appreciated. Here is my code below:

<div id="question{{question.Number}}" ng-repeat="question in questions" ng-class="question.ReliesOnID == null ? 'here' : 'hidden'">
    <div ng-if="question.QuestionTypeID == 3" >
        <div class="row">
            <div class="col-xs-12">
                <h5>{{question.Question}}</h5>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-2">
                <div class="col-xs-4"></div>
                <div class="col-xs-8">
                    <input type="radio" value="yes" name="{{question.Number}}"  /><label>Yes</label>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-2">
                <div class="col-xs-4"></div>
                <div class="col-xs-8">
                    <input type="radio" value="no" name="{{question.Number}}" /><label>No</label>
                </div>
            </div>
        </div>
    </div>
    <div ng-if="question.QuestionTypeID == 1">
        <div class="row">
            <div class="col-xs-12">
                <h5>{{question.Question}}</h5>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-4">
                <input type="text" class="form-control" />
            </div>
        </div>
    </div>
</div>


EDIT: Data structure is:

{
    "Active": true,
    "Comments": false,
    "DecimalPlaces": 0,
    "F": false,
    "FP": false,
    "Grouped": null,
    "ID": 20500,
    "Length": false,
    "MP": true,
    "Multiline": false,
    "Number": 45,
    "NumericOnly": false,
    "Optional": false,
    "Question": "How long ago was the treatment?",
    "QuestionID": 45,
    "QuestionSectionID": 2,
    "QuestionTypeID": 2,
    "QuestionnaireID": 298,
    "ReliesOnAnswer": true,
    "ReliesOnID": 44,
    "Weight": false
}
Share Improve this question edited Sep 13, 2016 at 14:51 RPichioli 3,3553 gold badges27 silver badges31 bronze badges asked Sep 13, 2016 at 11:25 Will2070Will2070 411 silver badge4 bronze badges 7
  • More explanation of the problem please. The question is not clear. – Rishul Matta Commented Sep 13, 2016 at 11:30
  • The problem is that i cannot show a question when i click on the yes radio button. So this question would have an id of question42 so i need to do find that element and show it on click of the radio button. In jquery i would have done something like function test(reliesonid) { $('#question' + reliesonid).show();} – Will2070 Commented Sep 13, 2016 at 11:33
  • @Will2070 Can you show us your jsfiddle to see the dependency of your questions, if possible show us your json object. – Mohit Tanwani Commented Sep 13, 2016 at 12:16
  • @Loading.. i've added the JSON object of a question above. THe relies on questionid is the number of the question that it relies on which is the Number property – Will2070 Commented Sep 13, 2016 at 12:33
  • @Will2070 I consider this json will be in ng-repeat as questions, and there will be each radio for each question, and once I check it yes, it will show the question with 44, is it ? – Mohit Tanwani Commented Sep 13, 2016 at 12:43
 |  Show 2 more ments

4 Answers 4

Reset to default 1

You need to use ng-model for your answers like:
<input type="radio" value="yes" ng-model="question.Answer" name="{{question.Number}}"/><label>Yes</label>

And then inside that question you could have sub questions and would just use ng-repeat.

ng-if="question.subQuestions && question.Answer !== undefined" ng-repeat="subquestion in question.subQuestions"

This will all depends on your question structure of course

EDIT
Based on your structure I would say you need an ng-if in your ng-repeat that could go something like this:
ng-if="!question.ReliesOnID || wasAnswered(question.ReliesOnID)"

In wasAnswered function you would need access to the questions array and filter for that ID and check if it was answered and return true or false

Try this snippet.

Is it something, you're looking for?

I tried to understand your question, and created an example based on your JSON data structure.

Based on the selection of particular question, it will show it's answer only.

Edit-1 : Applied Angular Element

If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or jqLite.

More information angular.element

You can do eliminate jQuery from code, if you want.

You can do the set / get class in Angular by using angular.element as shown over here.

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

myApp.controller('GreetingController', ['$scope', function($scope) {
  $scope.questions = [
    {
    "Active": true,
    "Comments": false,
    "DecimalPlaces": 0,
    "F": false,
    "FP": false,
    "Grouped": null,
    "ID": 20500,
    "Length": false,
    "MP": true,
    "Multiline": false,
    "Number": 45,
    "NumericOnly": false,
    "Optional": false,
    "Question": "How long ago was the treatment?",
    "QuestionID": 45,
    "QuestionSectionID": 2,
    "QuestionTypeID": 2,
    "QuestionnaireID": 298,
    "ReliesOnAnswer": true,
    "ReliesOnID": 10,
    "Weight": false,
    "Answer": '2 years ago'
    },
    {
    "Active": true,
    "Comments": false,
    "DecimalPlaces": 0,
    "F": false,
    "FP": false,
    "Grouped": null,
    "ID": 20500,
    "Length": false,
    "MP": true,
    "Multiline": false,
    "Number": 45,
    "NumericOnly": false,
    "Optional": false,
    "Question": "Who is God of cricket?",
    "QuestionID": 45,
    "QuestionSectionID": 2,
    "QuestionTypeID": 2,
    "QuestionnaireID": 298,
    "ReliesOnAnswer": true,
    "ReliesOnID": 20,
    "Weight": false,
    "Answer": 'Sachin Tendulkar'
    }
  ]
  
  //Function when radio button clicked
  $scope.flagChange = function(){
    var reliesId = angular.element(event.target).attr('data-reli-id');
    var value = angular.element(event.target).attr('data-value');
    //Based on the condition it will show / hide the respective element
    if(value == "yes")
    {
      $('#'+reliesId).removeClass('hide').addClass('show');
    }
    else
    {
      $('#'+reliesId).removeClass('show').addClass('hide');
    }
  }
}]);
.show
{
  display: block; 
}
.hide
{
  display: none; 
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="GreetingController">
  <div ng-repeat="question in questions track by $index">
        {{question.Question}}
        <input type="radio" name="Flag_{{$index}}" ng-click="flagChange($event)" data-value="yes" data-reli-id='{{question.ReliesOnID}}' />Yes
        <input type="radio" name="Flag_{{$index}}" ng-click="flagChange($event)" data-value="no" data-reli-id='{{question.ReliesOnID}}' />No
        <span ng-show="custom_$index">{{question.Answer}}</span>
    <br/>
        <div id="{{question.ReliesOnID}}" class="hide">
            Question based on ReliesOnID : {{question.ReliesOnID}}
        </div>
    <br/>
  </div> 
</div>

I dont like to use ng-if as that adds and removes the elements to the DOM. Below is a link to the ng-show/hide and a tutorial on how to use it on scotch.io.

https://docs.angularjs/api/ng/directive/ngShow

https://scotch.io/tutorials/how-to-use-ngshow-and-nghide

So a quick example would be below where the div element will only show when the variable is_active is true(this check can work with booleans or a text check). And this variable can be set in the controller or in the view. You dont need to toggle this. The div will automaticall hide when the evaluation is not true; so no need for a ng-hide and ng-show on the same element unless you are checking against multiple conditions.

<input type="radio" ng-model="question.subQuestion" value="true"> <br/>
 <input type="radio" ng-model="question.subQuestion" value="false"> <br/>

 <div ng-show="question.subQuestion">
     // Your subQuestion code es here
 </div>

Edit: based on ments below and provided data structure:

If assumed that you want to iterate just that questions which are parent and doesn't related on anything at start. Related should be display only when ratio is set on true:

So replace yourng-repeat with ng-repeat-start which will make you able iterate multiple divs not just on where ng-repeat is on.

In your <div> element add :

 <input type="radio" ng-model="question.subQuestion" value="true"> <br/>
 <input type="radio" ng-model="question.subQuestion" value="false"> <br/>

After that make another <div> below which will display your related questions. It can looks like:

// ng-if here to display only when radio was set to true
<div class="relatedQuestion" ng-repeat-end ng-if="question.subQuestion">
  <div ng-repeat="relatedQ in getRelatedQuestion(question.Number)">
    // Here you display your related questions
  </div>
</div>

So in your controller you need to add a function:

function getRelatedQuestion(number) {
  // logic es here which filter question
  // which have property relatedOnId === number;
  // it should be an array of objects to iteratee over it.
}


What you present as an option from JQUERY is possible in angular as well. However there is prolly even easier solution.

In your ng-repeat solution you replace your radio input with something like:

 <input type="radio" ng-model="question.subQuestion" value="true"> <br/>
 <input type="radio" ng-model="question.subQuestion" value="false"> <br/>

And then below you add this:

 <div ng-if="question.subQuestion">
     // Your subQuestion code es here
 </div>

Everything will be inside of your ng-repeat and should work correctly without additional logic in controller.

发布评论

评论列表(0)

  1. 暂无评论