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:
<divng-repeat="answer in question.Answer"><divng-if="!answer.isRemoved"><inputtype="radio"ng-change="select(question, answer)"ng-disabled="answer.isDisabled"ng-model="question.selectedAnswer"ng-value="answer.answertxt" /><strikeng-if="answer.isDisabled">{{answer.answertxt}}</strike><spanng-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) {
functiongetAnswer(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) {
varas = q.Answer;
for (i = 0; as.length; ++i) {
if (as[i].aId === aid) {
returnas[i];
}
}
}
}
functiondoHide(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);
}
}
}
}
functiondoRemove(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) {
varas = 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><htmlng-app="plunker"><head><metacharset="utf-8" /><title>AngularJS Plunker</title><script>document.write('<base href="' + document.location + '" />');
</script><linkrel="stylesheet"href="style.css" /><scriptdata-require="angular.js@1.3.x"src="https://code.angularjs.org/1.3.14/angular.js"data-semver="1.3.14"></script><scriptsrc="script.js"></script></head><bodyng-controller="MainCtrl"><divng-repeat="question in questions"><divclass="row"><br/><span>Q{{$index+1}}. {{question.questiontxt}}</span></div><divng-repeat="answer in question.Answer"><divng-if="!answer.isRemoved"><inputtype="radio"ng-change="select(question, answer)"ng-disabled="answer.isDisabled"ng-model="question.selectedAnswer"ng-value="answer.answertxt" /><strikeng-if="answer.isDisabled">{{answer.answertxt}}</strike><spanng-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><htmlng-app="plunker"><head><metacharset="utf-8" /><title>AngularJS Plunker</title><script>document.write('<base href="' + document.location + '" />');
</script><linkrel="stylesheet"href="style.css" /><scriptdata-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><bodyng-controller="MainCtrl"><divng-repeat="question in questions"><divclass="row"><br/><span>Q{{$index+1}}. {{question.questiontxt}}</span></div><divng-repeat="answer in question.Answer"><label><inputtype="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"