Reputation: 14922
I have a series of nested ng-repeat checkboxes, where it's a structure like:
The "select all" in each group should select all "country" checkboxes in that group.
You can see it in action here: http://plnkr.co/edit/rBIv9lfOr5MASPia7ORS?p=preview
The inner checkboxes are generated by an array in the main json:
$scope.carriers =
[{
"name": "UPS",
"selected": false,
"hasPaymentOptions": false,
"isSelectable": true,
"value": "",
"countries": [
"USA","UK","Canada","Germany","Australia"
]
},etc
And are in a nested ng-repeat:
<!-- main list of carrier checkboxes -->
<div ng-repeat="c in partnerent.carriers.carriers" class="spacer-top-md spacer-bottom-md">
<div class="carrier spacer-bottom-sm">
<div class="checkbox-inline">
<label>
<input type="checkbox" name="{{c.name | slug}}" ng-model="c.selected"> {{c.name}}
</label>
</div>
<!-- inner checkboxes for countries -->
<ul class="entitlement-countries list-inline">
<li ng-repeat="ec in c.countries">
<div class="checkbox-inline">
<label>
<input type="checkbox" name="{{ec | slug}}"> {{ec}}
</label>
</div>
</li>
<li ng-if="c.countries.length > 0">
<div class="checkbox-inline">
<label>
<input type="checkbox" name="{{ec | slug}}_selectall"> Select all
</label>
</div>
</li>
</ul>
It all works, but my question is how to have those "select all" checkboxes select their group of countries? Most of the solutions and directives I've found involve the model and are generally for one group of checkboxes, where I have several inside a ng-repeat.
Upvotes: 0
Views: 2742
Reputation: 1417
Plunker of my answer: http://plnkr.co/edit/d4cV1VP5iPj58ePGvZNR
Note: I didn't change all of the carriers, just the first one in the Plunker
How I would approach this would be to have some sort of ng-change
method on the selectAll & the child checkboxes:
<ul class="entitlement-countries list-inline">
<li ng-repeat="ec in c.countries">
<div class="checkbox-inline">
<label>
<input type="checkbox" name="{{ec.name | slug}}" ng-model="ec.selected" ng-change="checkAllCountriesSelected(c)"> {{ec}}
</label>
</div>
</li>
<li ng-if="c.countries.length > 0">
<div class="checkbox-inline">
<label>
<input type="checkbox" name="{{c.name | slug}}_selectall" ng-model="c.selectAll" ng-change="checkAllCountriesSelected(c)"> Select all
</label>
</div>
</li>
</ul>
And the data model would change slightly to:
$scope.carriers =
[{
"name": "UPS",
"selected": false,
"selectAll": false,
"hasPaymentOptions": false,
"isSelectable": true,
"value": "",
"countries": [
{ name: "USA", selected: false },
{ name: "UK", selected: false },
{ name: "Canada", selected: false },
{ name: "Germany", selected: false },
{ name: "Australia", selected: false }
]
},etc
And I'd add the change methods:
$scope.checkCountryToggled = function checkCountryToggled (carrier) {
var carrierCountriesSelected = getSelectedCountries(carrier);
if (carrierCountriesSelected.length === carrier.countries.length) {
carrier.selectAll = true;
} else {
carrier.selectAll = false;
}
};
function getSelectedCountries (carrier) {
var selectedCountries = filterFilter(carrier.countries, function (country) {
return country.selected;
});
return selectedCountries || [];
}
$scope.checkSelectAllToggled = function (carrier) {
if (carrier.selectAll) {
selectAllCountries(carrier);
}
};
function selectAllCountries (carrier) {
angular.forEach(carrier.countries, function (country) {
country.selected = true;
});
}
Upvotes: 0
Reputation: 5572
Use ng-checked
directive to select all the checkboxes.
<ul class="entitlement-countries list-inline">
<li ng-repeat="ec in c.countries">
<div class="checkbox-inline">
<label>
<input type="checkbox" name="{{ec | slug}}" ng-checked="c.countries.selectAll"> {{ec}}
</label>
</div>
</li>
<li ng-if="c.countries.length > 0">
<div class="checkbox-inline">
<label>
<input type="checkbox" name="{{ec | slug}}_selectall" ng-model="c.countries.selectAll"> Select all
</label>
</div>
</li>
</ul>
Here is the updated plnkr: http://plnkr.co/edit/o2NOBmFYZMtfkBu4lTrs?p=preview
Upvotes: 0