Can't execute selectall on checkboxes with Angular - javascript

I can't seem to figure out how to have another checkbox that selects all and deselects all boxes.
JSFIDDLE
<div ng-controller="tempCtrl">
<input type="checkbox" ng-model="selectAllOptions" ng-click="selectAll()" /> Select/Deselect All
<li ng-repeat="t in parameters.myMainOptions.teams">
<input ng-model="form.selectedTeams[t]" type="checkbox" />{{t}}</li>
<button class="btn btn-sm" type="submit" ng-click="submit(form)">SUBMIT</button> <pre>
{{form.selectedTeams}}
</pre>
</div>
var myApp = angular.module('myApp', []);
myApp.controller("tempCtrl", function ($scope) {
$scope.form = {
selectedTeams: {}
};
$scope.parameters = {
myMainOptions: {
teams: ['angels', 'giants', 'orioles', 'bluejays', 'athletics']
}
};
$scope.selectAll = function() {
//This is where I'm stuck
}
});

Here's a working plunkr of a simple select/deselect all checkbox:
plunkr
Controller
$scope.checkboxes = [
{
selected: false
},
{
selected: false
},
{
selected: false
}
];
// Check/uncheck all boxes
$scope.checkAll = function () {
angular.forEach($scope.checkboxes, function (obj) {
obj.selected = $scope.selectAll;
});
};
View
<p>Check all</p>
<input type="checkbox" ng-model="selectAll" ng-click="checkAll()" />
<br />
<p>Checkboxes</p>
<div ng-repeat="checkbox in checkboxes track by $index">
<input type="checkbox" ng-model="checkbox.selected" />
<label ng-show="checkbox.selected">Checkbox {{ $index+1 }} selected!</label>
</div>

First, you should make teams an array of objects like this
Controller:
$scope.parameters = {
myMainOptions: {
teams: [{name: 'angels'}, {name: 'giants'}, {name: 'orioles'}, {name:'bluejays'}, {name: 'athletics'}]
}
};
This is a better approach because, now, you can add a selected attribute to each team object.
Then you should set ng-model for each team checkbox to something like team.selected like this:
View:
<li ng-repeat="team in parameters.myMainOptions.teams">
<input ng-model="team.selected" type="checkbox" />
{{team}}
</li>
Now, if you check the angels checkbox, the object will change to {name: 'angels', selected: true}
Then your selectAll function will look like this:
Controller:
$scope.selectAll = function () {
angular.forEach($scope.parameters.myMainOptions.teams, function (team) {
team.selected = $scope.selectAllOptions;
});
};

You could do forEach on $scope.parameters.myMainOptions.teams array and then set $scope.form.selectedTeams value in the loop. Also use ng-change instead of ng-click.
Markup
<input type="checkbox" ng-model="selectAllOptions" ng-change="selectAll()" />Select/Deselect All
<li ng-repeat="t in parameters.myMainOptions.teams">
<input ng-model="form.selectedTeams[t]" type="checkbox" />{{t}}</li>
<button class="btn btn-sm" type="submit" ng-click="submit(form)">SUBMIT</button> <pre>
{{form.selectedTeams}}
</pre>
Code
$scope.selectAll = function () {
angular.forEach($scope.parameters.myMainOptions.teams, function (value, index) {
$scope.form.selectedTeams[value] = $scope.selectAllOptions; //setting selectAll variable value
})
}
Working Fiddle

Related

Check All checkbox function inside a modal

If user clicks 'add data' a modal opens, I have individual checkboxes for data1,data2,data3,data4. I also have a check all checkbox. If user clicks this, it should be able to select all above 4, if clicks again, it should deselect all. Also, once selected, the value of 'Select All' should change to 'Deselect All'
Code:
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-body">
<label><input type="checkbox" ng-model="checkboxModel.value1"> Data1</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value2"> Data2</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value3"> Data3</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value4"> Data4</label><br/>
<label><input type="checkbox" ng-model="checkboxModel.value5">Select All</label><br/>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
<button type="button" class="btn btn-default" ng-click="open()">Add data</button>
</div>
Can someone let me know how to achieve this. I saw a lot of posts online but each had ng-repeat for the first 4 checkboxes. Mine is without using ng-repeat. Can someone please advise.
I have the following plunker: http://plnkr.co/edit/nSCGJzj1zG5SGO2N76L3?p=preview
I noticed that you were not binding to the items array. I fixed that by using the following markup:
<div ng-repeat="item in items">
<label>
<input type="checkbox" ng-model="item.Selected">{{item.name}}</label>
<br/>
</div>
<label>
<input type="checkbox" ng-model="selectedAll" ng-click="checkAll()">Select All</label>
<br/>
After that, I had to change the structure of the items property to become an object for later binding:
$scope.items = [{
name: 'item 1'
}, {
name: 'item 2'
}, {
name: 'item 3'
}, ];
To be able to update all the other checkboxes, I resorted to the following code:
$scope.checkAll = function() {
if ($scope.selectedAll) {
$scope.selectedAll = true;
} else {
$scope.selectedAll = false;
}
angular.forEach($scope.items, function(item) {
item.Selected = $scope.selectedAll;
});
}
Please, refer to this plunker example for the full working solution.
UPDATE
Use the example here:
https://docs.angularjs.org/api/ng/directive/ngChecked#!
basically the trick is to add to all "slave" check boxes
ng-checked="checkboxModel.value5"
Well, first the explanation:
To select/deselect all the checkboxes, you can simply loop over the elements and setting all the checkbox to true/false.
To select/deselect this checkbox programatically, you can use Array.prototype.every() method, which returns if all checkboxes are selected or not, if all elements are selected that option will be/keep also selected, otherwise, it will be/keep deselected.
To get all the selected items when you close the modal you could use the Array.prototype.filter() method to return only the selected checkboxes.
Here's a snippet working:
(function() {
"use strict";
angular
.module('ui.bootstrap.demo', [
'ngAnimate',
'ui.bootstrap'
])
.controller('ModalDemoCtrl', ModalDemoCtrl)
.controller('ModalInstanceCtrl', ModalInstanceCtrl);
function ModalDemoCtrl($scope, $uibModal, $log) {
$scope.animationsEnabled = true;
$scope.open = function(size) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.items;
}
}
});
modalInstance.result.then(function(selectedItems) {
$scope.selected = selectedItems;
}, function() {
$log.info('Modal dismissed at: ', new Date());
});
}
$scope.toggleAnimation = function() {
$scope.animationsEnabled = !$scope.animationsEnabled;
}
}
// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.
function ModalInstanceCtrl($scope, $uibModalInstance, items) {
$scope.items = [];
function loadData() {
var arr = [];
for (var i = 1; i <= 5; i++) {
arr.push({
"name": "Item " + i
});
}
return arr;
}
$scope.items = loadData();
$scope.check = function() {
$scope.selectedAll = $scope.items.every(function(value) {
return value.Selected;
});
}
$scope.selectAll = function() {
$scope.items.forEach(function(item) {
item.Selected = $scope.selectedAll;
});
}
function getChecked() {
return $scope.items.filter(function(value) {
return value.Selected;
});
}
$scope.ok = function() {
$uibModalInstance.close(getChecked());
}
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
}
}
})();
.main_div {
border: 1px solid red;
width: 30%;
margin: 50px;
padding: 2px;
}
<!DOCTYPE HTML>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.0.0/ui-bootstrap-tpls.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-body">
<div class="checkbox" ng-repeat="item in items">
<label>
<input type="checkbox" ng-model="item.Selected" ng-change="check()"> {{item.name}}
</label>
<br/>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="selectedAll" ng-click="selectAll()"> Select All
</label>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
<button type="button" class="btn btn-default" ng-click="open()">Add data!</button>
</body>
</html>
If you want to see it in plunker, click here.
I hope it helps!!

Dynamic ng-model in ng-repeat

Using Angular JS, I have this object
var pages = [
{ name: 'users', title : "Users" },
{ name: 'roles', title : 'Roles' }
];
I'm trying to create a page for user roles. For that I need 4 checkboxes for each page. Each page must have 4 rules. Access, show, edit, delete.
Displaying pages in a ng-repeat
<div ng-controller='PageCtrl'>
<ul>
<li ng-repeat='page in pages'>
{{ page.title }}
<input type="checkbox" name="access"> Access
<input type="checkbox" name="show"> Show
<input type="checkbox" name="edit"> Edit
<input type="checkbox" name="delete"> Delete
</li>
</ul>
</div>
So I need to pass those checkboxes values to the $scope. How can I bind a model for each checkbox?
Like this
<input type="checkbox" name="access" ng-model='page.name+_access'> Access
Checkbox model name should start with page.name. Like users_access, users_show...
You can use the following syntax:
ng-model="page[page.name+'_access']"
But as a matter of fact, it looks one can move those groups into controller as well, then use another ng-repeat. Like this:
HTML:
<div ng-controller="PageCtrl">
<ul>
<li ng-repeat='page in pages'>{{ page.title }}
<label ng-repeat="right in rights">
<input type="checkbox" ng-model="page[page.name + '_' + right]" name="{{right}}" />{{right|capitalize}}</label>
<button ng-click="log(page)">Log</button>
</li>
</ul>
</div>
JS:
var module = angular.module('myAp', [])
.controller('PageCtrl', ['$scope', function ($scope) {
$scope.pages = [{
name: 'users',
title: "Users"
}, {
name: 'roles',
title: 'Roles'
}];
$scope.rights = ['access', 'show', 'edit', 'delete'];
$scope.log = function (page) {
console.log(page);
}
}]).filter('capitalize', function() {
return function (value) {
return value.charAt(0).toUpperCase() + value.slice(1);
};
});
Demo.

How to check/uncheck all check boxes using AngularJS?

I'm new in AngularJS and trying to achieve check/uncheck all check boxes by clicking "toggle" button, which is styled by bootstrap.
Markup:
<button id="toggle" class="btn btn-link btn-mini" ng-click="setActionTypesAllCheck()">Check all</button>
<div class="row-fluid" ng-repeat="at in actionsQuery.actionTypes">
<div class="checkbox">
<label><input type="checkbox" ng-model="at.checked">{{at.Description}}</label>
</div>
</div>
JavaScript:
$scope.setActionTypesAllCheck = function () {
$.each($scope.actionsQuery.actionTypes, function (i, cb) {
cb.checked = !cb.checked;
});
};
At this moment the code in JavaScript checks and unchecks all check boxes, but it doesn't take into account if some of them was manually checked/unchecked, which means it doesn't work properly.
So, I need to check all check boxes by clicking "toggle" button and change its name to "Uncheck all" no matter if some of check boxes is checked or not and vice versa, that is to uncheck all check boxes and change its name to "Check all" no matter if some of check boxes is checked or not.
var app = angular.module("app", []);
function MainCtrl() {
var vm = this;
vm.message = "Welcome";
vm.actionsQuery =
{
actionTypes: [
{
checked: true,
Description: "Jon"
}, {
checked: false,
Description: "Bon"
}, {
checked: false,
Description: "Tim"
}
]
};
vm.selected = function() {
}
vm.checkoxesState = true;
vm.UpdateCheckboxes = function() {
angular.forEach(vm.actionsQuery.actionTypes, function(at) {
at.checked = vm.checkoxesState;
});
vm.checkoxesState = !this.checkoxesState
};
}
angular.module("app").controller("MainCtrl", MainCtrl);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="app">
<body ng-controller="MainCtrl as vm">
<div class="container">
<h3>{{vm.message}}</h3>
<form>
<button id="toggle" class="btn btn-link btn-mini" ng-click="vm.UpdateCheckboxes()">
<span ng-show="vm.checkoxesState"> Check all </span>
<span ng-hide="vm.checkoxesState"> Uncheck All </span>
</button>
<div class="row-fluid" ng-repeat="at in vm.actionsQuery.actionTypes">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="at.checked">{{at.Description}}</label>
</div>
</div>
</form>
</div>
</body>
</html>
I have been using this directive for checkboxes. Its simple and it has examples that you need.

ng-click does nothing (todo list example)

I try to play around with some test in angular. but failed to add item in a todo list app sample:
app.controller('MainControl', function($scope){
$scope.tasks = [
{
"name":"task 1",
},
{"name":"task 2",
}
];
var addTask = function(){
$scope.tasks.push({
"name": $scope.input,
});
$scope.input = "";
};
});
I wonder why it doesn't work, no error in the console.
my html
<body ng-controller="MainControl">
<div>
<label>I want to:</label>
<input type="text" ng-model="input">
<button ng-click="addTask()">Add</button>
</div>
<div>
<ul ng-repeat="task in tasks">
<li>{{task.name}}</li>
</ul>
</div>
</body>
addTask must be a $scope property, i.e. $scope.addTask = function() {} instead of var addTask = function() {}.
Edit after comments:
<form ng-submit="addTask()">
<label>I want to:</label>
<input type="text" ng-model="input">
<button type="submit">Add</button>
</form>

AngularJS binding checkboxes to model property

I have an AngularJS app with a list of users with an 'Edit' button beside each user. Each user has a number of subjects associated with them. When I click on 'Edit', it opens a form in which you can edit user details, and select associated subjects from a list of checkboxes. I'm trying to figure out how to bind the subject checkboxes so that the subjects which the
user is already associated with are checked, and the rest are unchecked. Any suggestions appreciated.
My HTML:
<form name="UserEditForm">
Name: <br /> <input type="text" name="name" ng-model="user.name"> <br />
{{name}}
Email: <br /> <input type="text" name="name" ng-model="user.email"> <br />
{{email}}
<div class="control-group">
<label class="control-label" for="inputSubjects">Subjects:</label>
<div class="form-group">
<label ng-repeat="subject in subjects" class="checkbox">
<input type="checkbox" ng-checked="{user.subjects}" name="selectedSubjects[]" value="{{subject.id}}" ng-model="subject.selected"> {{subject.name}}
</label>
</div>
<br />
<a ng-click="updateUser()" class="btn btn-small btn-primary">Save Changes</a>
</form>
My UserEditCtrl:
angular.module('myApp.controllers')
.controller('UserEditCtrl', ['$scope', '$routeParams','SubjectsFactory', 'UserFactory', '$location',
function ($scope, $routeParams, SubjectsFactory, UserFactory, $location) {
// callback for ng-click 'updateUser':
$scope.updateUser = function () {
$scope.user.subjects = $scope.selection;
UserFactory.update($scope.user);
$location.path('/users');
};
// callback for ng-click 'cancel':
$scope.cancel = function () {
$location.path('/users');
};
$scope.user = UserFactory.show({id: $routeParams.userid});
$scope.subjects = SubjectsFactory.query();
$scope.selection = [];
// helper method
$scope.selectedSubjects = function selectedSubjects() {
return filterFilter($scope.subjects, { selected: true });
};
// watch subjects for changes
$scope.$watch('subjects|filter:{selected:true}', function (nv) {
$scope.selection = nv.map(function (subject) {
return subject.id;
});
}, true);
}]);
As #jkinkead said, your code looks good, I fixed the ng-checked binding in accordance with your ng-model expression
Here's a simplified plunker : http://plnkr.co/edit/qaIBExtVbNdSXlQlbMym?p=preview
EDIT 1: I edited and improved the plunker to get closer to your case.

Categories