Ng-repeat Hiding Radio Button Based On Radio Answer Selected
Solution 1:
A straight-forward way would be to augment your 'answer' data structures with two new arrays, 'hides' and 'removes', which upon selection would disable or by case remove the targeted answers of other questions. For example,
...
Answer: [{
answertxt: "answer11",
aId: 83493,
hides: [{
qid: 5678,
aId: 67107
}],
removes: [{
qid: 4321,
aId: 32342
}]
},
...
answer11 hides answer22 and removes answer31.
Your html would then boil down to the following display logic:
<div ng-repeat="answer in question.Answer">
<div ng-if="!answer.isRemoved">
<input type="radio"
ng-change="select(question, answer)"
ng-disabled="answer.isDisabled"
ng-model="question.selectedAnswer"
ng-value="answer.answertxt" />
<strike ng-if="answer.isDisabled">{{answer.answertxt}}</strike>
<span ng-if="!answer.isDisabled">{{answer.answertxt}}</span>
</div>
</div>
where the isRemoved
and isDisabled
flags are set on answer selection in select(question, answer)
.
Full working example:
var app = angular.module('plunker', []);
app.controller('MainCtrl', ['$scope',
function($scope) {
function getAnswer(qid, aid) {
var qs = $scope.questions, q;
for (var i = 0; i < qs.length; ++i) {
if (qs[i].qid === qid) {
q = qs[i];
break;
}
}
if (q) {
var as = q.Answer;
for (i = 0; as.length; ++i) {
if (as[i].aId === aid) {
return as[i];
}
}
}
}
function doHide(q, a) {
if (a.hides && a.hides.length) {
for (var i = 0; i < a.hides.length; ++i) {
var h = a.hides[i],
answer = getAnswer(h.qid, h.aId);
if (answer) {
answer.isDisabled = (q.selectedAnswer == a.answertxt);
}
}
}
}
function doRemove(q, a) {
if (a.removes && a.removes.length) {
for (var i = 0; i < a.removes.length; ++i) {
var r = a.removes[i],
answer = getAnswer(r.qid, r.aId);
if (answer) {
answer.isRemoved = (q.selectedAnswer == a.answertxt);
}
}
}
}
$scope.select = function (q, a) {
var as = q.Answer;
for (var i = 0; i < as.length; ++i) {
var answer = as[i];
doHide(q, answer);
doRemove(q, answer);
}
};
$scope.questions = [{
questiontxt: 'Please select your Age range',
qid: 1234,
Answer: [{
answertxt: "answer11",
aId: 83493,
hides: [{
qid: 5678,
aId: 67107
}],
removes: [{
qid: 4321,
aId: 32342
}]
}, {
answertxt: "answer12",
aId: 1223,
removes: [{
qid: 4321,
aId: 79130
}]
}, {
answertxt: "answer13",
aId: 1223
}]
},
{
questiontxt: 'Please select your favorite activity',
qid: 5678,
Answer: [{
answertxt: "answer21",
aId: 90886
}, {
answertxt: "answer22",
aId: 67107
}]
},
{
questiontxt: 'Please select your favorite food',
qid: 4321,
Answer: [{
answertxt: "answer31",
aId: 32342
}, {
answertxt: "answer32",
aId: 79130
}]
}
];
}
]);
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.14/angular.js" data-semver="1.3.14"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="question in questions">
<div class="row">
<br/><span>Q{{$index+1}}. {{question.questiontxt}}</span>
</div>
<div ng-repeat="answer in question.Answer">
<div ng-if="!answer.isRemoved">
<input type="radio"
ng-change="select(question, answer)"
ng-disabled="answer.isDisabled"
ng-model="question.selectedAnswer"
ng-value="answer.answertxt" />
<strike ng-if="answer.isDisabled">{{answer.answertxt}}</strike>
<span ng-if="!answer.isDisabled">{{answer.answertxt}}</span>
</div>
</div>
</div>
</body>
</html>
Solution 2:
Could add a property like:
disables: [{ selectedAnswer: 83493,otherQ: 5678, otherAnswerId: 90886 }]
to each question along with ng-disbled
and ng-change
to each radio
The methodology is to look at all the disables
above and then check the corresponding other question and other answer and see if the currently selected answer matches the selectedAnswer
in the disable object
var app = angular.module('plunker', []);
app.controller('MainCtrl', ['$scope',
function($scope) {
$scope.disableMatches = function(question, answer) {
let selectedId = question.selectedAnswer;
question.disables.forEach(function(o) {
let otherQ = $scope.questions.find(function(q) {
return q.qid == o.otherQ
});
let otherAnswer = otherQ.Answer.find(function(ans) {
return ans.aId === o.otherAnswerId
})
otherAnswer.disabled = selectedId == o.selectedAnswer;
});
}
$scope.questions = [{
questiontxt: 'Please select your Age range',
qid: 1234,
disables: [{
selectedAnswer: 83493,
otherQ: 5678,
otherAnswerId: 90886
}],
Answer: [{
answertxt: "answer11 Disables answer 21",
aId: 83493
}, {
answertxt: "answer12",
aId: 1223
}, {
answertxt: "answer13",
aId: 1223
}]
},
{
questiontxt: 'Please select your favorite activity',
qid: 5678,
Answer: [{
answertxt: "answer21",
aId: 90886
}, {
answertxt: "answer22",
aId: 67107
}]
},
{
questiontxt: 'Please select your favorite food',
qid: 4321,
Answer: [{
answertxt: "answer31",
aId: 32342
}, {
answertxt: "answer32",
aId: 79130
}]
}
];
}
]);
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.14/angular.js" data-semver="1.3.14"></script>
<script>
</script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="question in questions">
<div class="row">
<br/><span>Q{{$index+1}}. {{question.questiontxt}}</span>
</div>
<div ng-repeat="answer in question.Answer">
<label>
<input type="radio"
name="radio{{$parent.$index}}"
ng-change="disableMatches(question)"
ng-disabled="answer.disabled"
ng-model="question.selectedAnswer"
ng-value="{{answer.aId}}" />{{answer.answertxt}}</label>
</div>
</div>
</body>
</html>
Post a Comment for "Ng-repeat Hiding Radio Button Based On Radio Answer Selected"