Reputation: 445
I have to deal with a situation where there will be a question and its answers will be dynamically generated. The issue is when i add one question and add its answers then when i add another question then it already contains the same answers as above question.
For Example: Q. Select ice cream flavour A. Chocolate B. Vanilla
Now When i Add another question Q. Select ice cream company Now, here it shows A. Chocolate B. Vanilla
Following is my code :
<div class="col-lg-12">
<div ng-controller="CustomizationCtrlr">
<form name="CustomizationForm" ng-submit="SaveCustomization(CustomizationForm.$valid)" novalidate>
<div>
<div class="inputDiv">
@Html.TextBoxFor(model => model.GroupTitle, new { name = "GroupTitle", ng_model = "QuestionGroup.GroupTitle", @class = "form-control", maxlength = "65", placeholder = "GroupTitle" })
<br />
</div>
<div class="formgroup" ng-repeat="Question in Questions">
<div class="inputDiv form-group" id="" ng-repeat="QuestionItem in QuestionItems" >
@Html.TextBoxFor(model => model.QuestionItemText, new { name = "QuestionItemText", ng_model = "QuestionItem.Text", @class = "form-control", placeholder = "Question Item Text", required = "required" })
<button ng-show="showAddQuestionItem(QuestionItem)" ng-click="AddQuestionItem($parent.$index)">Add question item</button>
<br />
</div>
<button ng-show="showAddQuestion(Question)" ng-click="AddQuestion()">Add question</button>
</div>
</div>
<button type="submit" name="btnPost" class="btn save-btn" onclick="ValidateForm()">Save Customizations</button>
</form>
</div>
</div>
And following is my script:
<script>
var app = angular.module('ProductCatalog.controllers', [])
.controller('CustomizationCtrlr', function ($scope, $http) {
$scope.AddQuestionItem = function (parentIndex) {
var newItemNo = $scope.QuestionItems.length + 1 + "-" + parentIndex;
$scope.QuestionItems.push({ 'id': 'qi' + newItemNo });
}
$scope.showAddQuestionItem = function (QuestionItem) {
return QuestionItem.id === $scope.QuestionItems[$scope.QuestionItems.length - 1].id;
};
$scope.QuestionItems = [{ id: 'qi1', Text: '' }];
$scope.AddQuestion = function () {
var newItemNo = $scope.Questions.length + 1;
$scope.Questions.push({ 'id': 'q' + newItemNo });
}
$scope.showAddQuestion = function (Question) {
return Question.id === $scope.Questions[$scope.Questions.length - 1].id;
};
$scope.Questions = [{ id: 'q1', Text: '' }];
})
</script>
Upvotes: 0
Views: 218
Reputation: 21
You always iterate over the same reference of QuestionItems on your scope.
If you want to connect the answers to the question you need to somehow create unique answer arrays per question
One way to do it is save the answers in the question instance in a property and then ng-repeat that
<div class="formgroup" ng-repeat="Question in Questions">
<div class="inputDiv form-group" id="" ng-repeat="QuestionItem in Question.QuestionItems" >
@Html.TextBoxFor(model => model.QuestionItemText, new { name = "QuestionItemText", ng_model = "QuestionItem.Text", @class = "form-control", placeholder = "Question Item Text", required = "required" })
<button ng-show="showAddQuestionItem(QuestionItem)" ng-click="AddQuestionItem($parent.$index, Question)">Add question item</button>
<br />
</div>
And in the JS:
$scope.Questions = [{ id: 'q1', Text: '', QuestionItems: [{ id: 'qi1', Text: '' }] }];
$scope.AddQuestionItem = function (parentIndex, parentQuestion) {
var newItemNo = $scope.QuestionItems.length + 1 + "-" + parentIndex;
parentQuestion.QuestionItems.push({ 'id': 'qi' + newItemNo });
}
Upvotes: 2
Reputation: 4401
The approach you have contains different scope for Questions and QuestionItems. Whenever, you add a new Question, the Question Items is already populated with previous entries from the previous input.
There is a need to change the data structure here, keep an array of questions and a property within an array for the Question Items.
$scope.Questions = [{
"Id": "q1",
"QuestionItems": [{
"Id": "qi1",
"Text": ""
}]
}]
This way you can have Question and its items grouped together.
See the snippet below, I had to remove the .net controls for the demo purpose, you can replace the input
with the razor controls you had earlier.
var app = angular.module("MyApp", []);
app.controller('CustomizationCtrlr', function($scope, $http) {
$scope.Questions = [{
"Id": "q1",
"QuestionItems": [{
"Id": "qi1",
"Text": ""
}]
}]
$scope.AddQuestionItem = function(ques) {
var newItemNo = ques.QuestionItems.length + 1
ques.QuestionItems.push({
'Id': 'qi' + newItemNo,
"Text": ""
});
}
$scope.showAddQuestionItem = function(QuestionItem) {
return QuestionItem.id === $scope.QuestionItems[$scope.QuestionItems.length - 1].id;
};
$scope.AddQuestion = function() {
var newItemNo = $scope.Questions.length + 1;
$scope.Questions.push({
"Id": "q" + newItemNo,
"QuestionItems": [{
"Id": "qi1",
"Text": ""
}]
});
}
$scope.showAddQuestion = function(Question) {
return Question.id === $scope.Questions[$scope.Questions.length - 1].id;
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="MyApp">
<div class="col-lg-12">
<div ng-controller="CustomizationCtrlr">
<form name="CustomizationForm" ng-submit="SaveCustomization(CustomizationForm.$valid)" novalidate>
<div>
<div class="inputDiv">
<input type="text" ng-model="QuestionGroup.GroupTitle" placeholder="GroupTitle" />
<br />
</div>
<div class="formgroup" ng-repeat="Question in Questions">
<div class="inputDiv form-group" id="" ng-repeat="QuestionItem in Question.QuestionItems">
<input type="text" ng-model="QuestionItem.Text" placeholder="Question Item Text" />
<button ng-click="AddQuestionItem(Question)">Add question item</button>
<br />
</div>
<button ng-click="AddQuestion()">Add question</button>
</div>
</div>
<button type="submit" name="btnPost" class="btn save-btn" onclick="ValidateForm()">Save Customizations</button>
</form>
<pre>{{Questions | json}}</pre>
</div>
</div>
</body>
Upvotes: 1