I have a few checkboxes:
If you have multiple checkboxes on the same form
The controller code
vm.doYouHaveCheckBox = ['aaa', 'ccc', 'bbb'];
vm.desiredRoutesCheckBox = ['ffffd', 'ccc', 'Default'];
vm.doYouHaveCBSelection = [];
vm.desiredRoutesCBSelection = [];
View code
<div ng-repeat="doYouHaveOption in vm.doYouHaveCheckBox">
<div class="action-checkbox">
<input id="{{doYouHaveOption}}" type="checkbox" value="{{doYouHaveOption}}" ng-checked="vm.doYouHaveCBSelection.indexOf(doYouHaveOption) > -1" ng-click="vm.toggleSelection(doYouHaveOption,vm.doYouHaveCBSelection)" />
<label for="{{doYouHaveOption}}"></label>
{{doYouHaveOption}}
</div>
</div>
<div ng-repeat="desiredRoutesOption in vm.desiredRoutesCheckBox">
<div class="action-checkbox">
<input id="{{desiredRoutesOption}}" type="checkbox" value="{{desiredRoutesOption}}" ng-checked="vm.desiredRoutesCBSelection.indexOf(desiredRoutesOption) > -1" ng-click="vm.toggleSelection(desiredRoutesOption,vm.desiredRoutesCBSelection)" />
<label for="{{desiredRoutesOption}}"></label>
{{desiredRoutesOption}}
</div>
</div>
Here is the jsFillde link for the same, http://jsfiddle.net/techno2mahi/Lfw96ja6/.
This uses the directive which is available for download at http://vitalets.github.io/checklist-model/.
This is the good to have directive as your application will need this functionality much often.
The code is below:
<div class="container">
<div class="ng-scope" ng-app="app" ng-controller="Ctrl1">
<div class="col-xs-12 col-sm-6">
<h3>Multi Checkbox List Demo</h3>
<div class="well"> <!-- ngRepeat: role in roles -->
<label ng-repeat="role in roles">
<input type="checkbox" checklist-model="user.roles" checklist-value="role"> {{role}}
</label>
</div>
<br>
<button ng-click="checkAll()">check all</button>
<button ng-click="uncheckAll()">uncheck all</button>
<button ng-click="checkFirst()">check first</button>
<div>
<h3>Selected User Roles </h3>
<pre class="ng-binding">{{user.roles|json}}</pre>
</div>
<br>
<div><b/>Provided by techno2Mahi</b></div>
</div>
var app = angular.module("app", ["checklist-model"]);
app.controller('Ctrl1', function($scope) {
$scope.roles = [
'guest',
'user',
'customer',
'admin'
];
$scope.user = {
roles: ['user']
};
$scope.checkAll = function() {
$scope.user.roles = angular.copy($scope.roles);
};
$scope.uncheckAll = function() {
$scope.user.roles = [];
};
$scope.checkFirst = function() {
$scope.user.roles.splice(0, $scope.user.roles.length);
$scope.user.roles.push('guest');
};
});
There are two ways to approach this problem. Either use a simple array or an array of objects. Each solution has it pros and cons. Below you'll find one for each case.
The HTML could look like:
<label ng-repeat="fruitName in fruits">
<input
type="checkbox"
name="selectedFruits[]"
value="{{fruitName}}"
ng-checked="selection.indexOf(fruitName) > -1"
ng-click="toggleSelection(fruitName)"
> {{fruitName}}
</label>
And the appropriate controller code would be:
app.controller('SimpleArrayCtrl', ['$scope', function SimpleArrayCtrl($scope) {
// Fruits
$scope.fruits = ['apple', 'orange', 'pear', 'naartjie'];
// Selected fruits
$scope.selection = ['apple', 'pear'];
// Toggle selection for a given fruit by name
$scope.toggleSelection = function toggleSelection(fruitName) {
var idx = $scope.selection.indexOf(fruitName);
// Is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
// Is newly selected
else {
$scope.selection.push(fruitName);
}
};
}]);
Pros: Simple data structure and toggling by name is easy to handle
Cons: Add/remove is cumbersome as two lists (the input and selection) have to be managed
The HTML could look like:
<label ng-repeat="fruit in fruits">
<!--
- Use `value="{{fruit.name}}"` to give the input a real value, in case the form gets submitted
traditionally
- Use `ng-checked="fruit.selected"` to have the checkbox checked based on some angular expression
(no two-way-data-binding)
- Use `ng-model="fruit.selected"` to utilize two-way-data-binding. Note that `.selected`
is arbitrary. The property name could be anything and will be created on the object if not present.
-->
<input
type="checkbox"
name="selectedFruits[]"
value="{{fruit.name}}"
ng-model="fruit.selected"
> {{fruit.name}}
</label>
And the appropriate controller code would be:
app.controller('ObjectArrayCtrl', ['$scope', 'filterFilter', function ObjectArrayCtrl($scope, filterFilter) {
// Fruits
$scope.fruits = [
{ name: 'apple', selected: true },
{ name: 'orange', selected: false },
{ name: 'pear', selected: true },
{ name: 'naartjie', selected: false }
];
// Selected fruits
$scope.selection = [];
// Helper method to get selected fruits
$scope.selectedFruits = function selectedFruits() {
return filterFilter($scope.fruits, { selected: true });
};
// Watch fruits for changes
$scope.$watch('fruits|filter:{selected:true}', function (nv) {
$scope.selection = nv.map(function (fruit) {
return fruit.name;
});
}, true);
}]);
Pros: Add/remove is very easy
Cons: Somewhat more complex data structure and toggling by name is cumbersome or requires a helper method
Demo: http://jsbin.com/ImAqUC/1/
A simple solution:
<div ng-controller="MainCtrl">
<label ng-repeat="(color,enabled) in colors">
<input type="checkbox" ng-model="colors[color]" /> {{color}}
</label>
<p>colors: {{colors}}</p>
</div>
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope){
$scope.colors = {Blue: true, Orange: true};
});
</script>
http://plnkr.co/edit/U4VD61?p=preview
Another simple directive could be like:
var appModule = angular.module("appModule", []);
appModule.directive("checkList", [function () {
return {
restrict: "A",
scope: {
selectedItemsArray: "=",
value: "@"
},
link: function (scope, elem) {
scope.$watchCollection("selectedItemsArray", function (newValue) {
if (_.contains(newValue, scope.value)) {
elem.prop("checked", true);
} else {
elem.prop("checked", false);
}
});
if (_.contains(scope.selectedItemsArray, scope.value)) {
elem.prop("checked", true);
}
elem.on("change", function () {
if (elem.prop("checked")) {
if (!_.contains(scope.selectedItemsArray, scope.value)) {
scope.$apply(
function () {
scope.selectedItemsArray.push(scope.value);
}
);
}
} else {
if (_.contains(scope.selectedItemsArray, scope.value)) {
var index = scope.selectedItemsArray.indexOf(scope.value);
scope.$apply(
function () {
scope.selectedItemsArray.splice(index, 1);
});
}
}
console.log(scope.selectedItemsArray);
});
}
};
}]);
The controller:
appModule.controller("sampleController", ["$scope",
function ($scope) {
//#region "Scope Members"
$scope.sourceArray = [{ id: 1, text: "val1" }, { id: 2, text: "val2" }];
$scope.selectedItems = ["1"];
//#endregion
$scope.selectAll = function () {
$scope.selectedItems = ["1", "2"];
};
$scope.unCheckAll = function () {
$scope.selectedItems = [];
};
}]);
And the HTML:
<ul class="list-unstyled filter-list">
<li data-ng-repeat="item in sourceArray">
<div class="checkbox">
<label>
<input type="checkbox" check-list selected-items-array="selectedItems" value="{{item.id}}">
{{item.text}}
</label>
</div>
</li>
I'm also including a Plunker: http://plnkr.co/edit/XnFtyij4ed6RyFwnFN6V?p=preview
<input type='checkbox' ng-repeat="fruit in fruits"
ng-checked="checkedFruits.indexOf(fruit) != -1" ng-click="toggleCheck(fruit)">
.
function SomeCtrl ($scope) {
$scope.fruits = ["apple, orange, pear, naartjie"];
$scope.checkedFruits = [];
$scope.toggleCheck = function (fruit) {
if ($scope.checkedFruits.indexOf(fruit) === -1) {
$scope.checkedFruits.push(fruit);
} else {
$scope.checkedFruits.splice($scope.checkedFruits.indexOf(fruit), 1);
}
};
}