Reputation: 4480
In my Angular app, I have the following list of checkboxes, generated within a nested ng-repeat
:
<div ng-repeat="type in boundaryPartners">
<div class="row" ng-show="showBPtype[$index]">
<div class="col-xs-12">
<div ng-repeat="partner in type.partners">
<label class="checkbox-inline">
<input type="checkbox"
value="partner.id"
ng-model="partner.selected"
ng-change="changeValue(partner)"
/>
<p><span ></span>{{partner.name}}<p>
</label>
</div>
</div>
</div>
</div>
This list is retrieved from a data and has the following structure (sample):
{
"id": 1,
"name": "Civil Society Organizations",
"partners": [{
"id": 1,
"name": "Youth Association"
}, {
"id": 2,
"name": "Rwanda Network"
}, {
"id": 3,
"name": "Communité du Rwanda"
}]
},
{
"id": 2,
"name": "Educational Organizations",
"partners": [{
"id": 16,
"name": "SchoolA"
}, {
"id": 17,
"name": "SchoolB"
}]
}
This is an array of objects, which represent the type
of partner, which each contain a list of partners of that time, within the array partners
.
This will end up looking like the picture below:
When a user selects a partner with a chekcbox, this partner is supposed to get added to a nested list of selected partners (following a similar structure), and when a user deselects a checkbox, that partner is to be deleted.
I already have a working solution for a single list of partners which was provided by user Artyom Pranovich in his answer (all credit to him).
This is his code:
var partnersList = [], idsArray = [];
$scope.changeValue = function(partner){
if(partner.selected)
addPartner(partner);
else
removePartner(partner);
};
var addPartner= function(partner){
if(!existInList(partner))
partnersList.push(partner);
};
var removePartner= function(partner){
idsArray = getIdsArray();
var indexToRemove = idsArray.indexOf(partner.id);
if(indexToRemove == -1)
return;
partnersList.splice(indexToRemove, 1);
};
var existInList = function(partner){
idsArray = getIdsArray();
return idsArray.indexOf(partner.id) != -1;
};
var getIdsArray = function(){
return partnersList.map(function(partner){ return partner.id });
};
However, using the interface I described above, I need to populate a nested list of partners, containing only the partners which where selected by the user, with the same structure as the one I described before: a list of partner objects, organized by type (which has an type.id
number and a type.partners
array).
I've tried some solutions using $parent.$index
and $index
to locate which partner I should be adding/removing when necessary, but I can't seem to wrap my head around this.
What would be the best way to adapt the suggested code to my needs?
EDIT: adding the structure of the final list containing the selected partners (i. e. the list where partners will have to get pushed to), as requested. Sample:
[
{
"id": 1,
"entities": [
{
"id": 2,
"name": "Entity 2"
},
{
"id": 3,
"name": "Entity 3"
}
]
},
{
"id": 2,
"entities": [
{
"id": 2,
"name": "Entity 2"
}
]
}
]
Within the app, this list is called $scope.report.participatingPartners
.
Upvotes: 0
Views: 611
Reputation: 6962
If I've understood your problem, the solution will be similar with it.
If you have questions, don't hesitate to ask.
<div ng-repeat="organization in boundaryPartners">
<div ng-repeat="partner in organization.partners">
<label>
<input type="checkbox" value="partner.id" ng-model="partner.selected"
ng-change="changeValue(partner, organization, $parent.$index)"/>
{{partner.name}}
</label>
</div>
<hr/>
</div>
$scope.participatingPartners = []
var idsArray = [];
$scope.changeValue = function(partner, organization, index){
if(partner.selected)
addPartner(partner, organization, index);
else
removePartner(partner, organization, index);
};
var addPartner= function(partner, organization, index){
prepareArrayToAdd(organization, index);
if(!existInList(index, partner)){
$scope.participatingPartners[index].partners.push(partner);
}
};
var prepareArrayToAdd = function(organization, index){
if(!$scope.participatingPartners[index])
$scope.participatingPartners[index] = { id: organization.id, name: organization.name, partners: [] };
};
var removePartner= function(partner, organization, index){
idsArray = getIdsArray(index);
var indexToRemove = idsArray.indexOf(partner.id);
if(indexToRemove == -1)
return;
$scope.participatingPartners[index].partners.splice(indexToRemove, 1);
};
var existInList = function(index, partner){
idsArray = getIdsArray(index);
return idsArray.indexOf(partner.id) != -1;
};
var getIdsArray = function(index){
return $scope.participatingPartners[index].partners.map(function(partner){ return partner.id });
};
JSFIddle link.
Hope it helps!
Upvotes: 1