Select all the checkboxes inside the same loop iteration using AngularJS - javascript

What I'm trying to achieve is to check some checkboxes belonging to a ng-repeat loop iteration when I check a "master" checkbox. My code so far in the view:
<div ng-app="CheckAllModule">
<div ng-controller="checkboxController">
<ul ng-repeat="s in struct">
<li><strong>{{s}} item</strong>
<input type="checkbox" ng-checked="x1 && x2 && x3" ng-model="selectedAll" ng-click="checkAll()" />
</li>
<label>Subitem A
<input type="checkbox" ng-checked="chk" ng-model="x1" />
</label>
<label>Subitem B
<input type="checkbox" ng-checked="chk" ng-model="x2" />
</label>
<label>Subitem C
<input type="checkbox" ng-checked="chk" ng-model="x3" />
</label>
</ul>
</div>
</div>
Where the first checkbox is the "master" and should impose its own state to the "slaves" (the next three checkboxes), no matter what was their previous state.
Regarding to the slave checkboxes, they should be checked & unchecked indepently. But If the three are checked at the same time, the master should be too. Whenever only one of them is not checked, the master shouldn't be as well.
And my controller:
var app = angular.module("CheckAllModule", []);
app.controller("checkboxController", function ($scope) {
$scope.struct = ['First', 'Second'];
$scope.checkAll = function () {
if ($scope.selectedAll) {
$scope.chk = true;
} else {
$scope.chk = false;
}
};
});

This almost certainly doesn't follow best practices but I'm a noob with Angular. It does work though:
http://plnkr.co/edit/oGNC3ZUZHDHrBrMyRKjW?p=preview
var app = angular.module("CheckAllModule", []);
app.controller("checkboxController", function($scope) {
$scope.struct = ['First', 'Second'];
$scope.checkAll = function(selected, chkArray) {
for (var chk in chkArray) {
chkArray[chk] = selected
}
};
});
I made some adjustments to your html to get this working:
<div ng-app="CheckAllModule">
<div ng-controller="checkboxController">
<ul ng-repeat="s in struct" data-ng-init="x[1]=false;x[2]=false;x[3]=false">
<li>
<strong>{{s}} item</strong>
<input type="checkbox" ng-checked="x[1] && x[2] && x[3]" ng-model="selectedAll" ng-click="checkAll(selectedAll, x)" />
</li>
<label>Subitem A
<input type="checkbox" ng-model="x[1]" />
</label>
<label>Subitem B
<input type="checkbox" ng-model="x[2]" />
</label>
<label>Subitem C
<input type="checkbox" ng-model="x[3]" />
</label>
</ul>
</div>
</div>
Update
I was thinking about how better to test x1 && x2 && x3 the conversion to an array was the first step but then you can do:
x.indexOf(false)
(Ideally you would use .reduce(function(a,b) { return a && b; }) but reduce is not yet well enough supported and to be fair, it's a bit more clunky) - strangely this is not working yet.

Working Plunkr Here
As a note, you should always try to bind to something using dot notation.
<ul ng-repeat="s in struct track by $index">
<li>
<strong>{{s.Item}} item</strong>
<input type="checkbox" ng-click="checkAll(s.selectedAll,$index)" ng-model="s.selectedAll" ng-checked="s.x1 && s.x2 && s.x3" />
</li>
<label>Subitem A
<input type="checkbox" ng-checked="s.chk" ng-model="s.x1" />
</label>
<label>Subitem B
<input type="checkbox" ng-checked="s.chk" ng-model="s.x2" />
</label>
<label>Subitem C
<input type="checkbox" ng-checked="s.chk" ng-model="s.x3" />
</label>
</ul>
The situation you have here is that you ng-repeat is bound to a list of strings. You should know that when repeating on a collection each item then would have it's own scope and maintain their values independently. This is hard to do since you can not add these values to a string (you need to bind to an object that can be expanded on).
I have made the adjustments that would allow for this particular setup. It should be agreeable as minor changes have been made.

Related

How to filter ng-repeat data based on true false condition

sorry if this has been solved before, but I can't find an asnwer to it.
I am trying to sort an ng-repeat according to the selection on radio buttons,
but I simply can't figure how to hide and show the items in the ng-repeat.
An example:
html:
<form>
<label><input type="radio" name="generic" />all</label>
<label><input type="radio" name="generic" />offline</label>
</form>
<div ng-repeat="channel in controller.channelArray>
<div>{{channel.name}}</div>
</div>
javascript:
channelArray = [];
pushStreams();
function pushStreams(data) {
channelArray.push(data)
}
Now, this is just an example, and I haven't tested this code, but it works in my real code.
I just want to know, assuming the data contains a status variable that is either false a true, how to show all (both false and true) and how to filter out trues if I select the offline radio button.
Hope this is clear enough, thanks!
For this , you can use ng-if directive.
The ng-if directive removes or recreates a portion of the DOM tree
based on an {expression}.
<div ng-repeat="channel in channels">
<div ng-if="validate(channel)">{{channel.name}}</div>
</div>
function TodoCtrl($scope) {
$scope.check='All';
$scope.channels=[{
name:'a',
status:true
},{
name:'b',
status:false
},{
name:'c',
status:false
},{
name:'d',
status:true
}];
$scope.validate=function(channel){
switch($scope.check){
case 'All':
return true;
case 'Offline':
return !channel.status;
case 'Online':
return channel.status;
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<label><input type="radio" name="generic" ng-model="check" value="All" />all</label>
<label><input type="radio" name="generic" ng-model="check" value="Offline" />offline</label>
<label><input type="radio" name="generic" ng-model="check" value="Online" />online</label>
<div ng-repeat="channel in channels">
<div ng-if="validate(channel)">{{channel.name}}</div>
</div>
</div>
</div>
<form>
<label><input type="radio" name="generic" ng-model="all" checked />all</label>
<label><input type="radio" name="generic" ng-model="offline" />offline</label>
</form>
<div ng-if="all" ng-repeat="channel in controller.channelArray">
<div>{{channel.name}}</div>
</div>
<div ng-if="offline" ng-repeat="channel in controller.channelArray | filter :{status:true}">
<div>{{channel.name}}</div>
</div>
you can use filters for that and if all means the first div will display and if you click on offline means the second div will display for the status true if you want to change the status the change the filter value also
First you need to add ng-model directive's and value attributes to your radio buttons. The value will get stored in the main.selectedFilter variable (where it can be used in the filter later).
HTML:
<body ng-controller="MainCtrl as main">
<form>
<label><input type="radio" name="generic" ng-model="main.selectedFilter" value="All" />all</label>
<label><input type="radio" name="generic" ng-model="main.selectedFilter" value="Offline" />Offline</label>
</form>
<div ng-repeat="channel in main.channelArray | filter : main.myFilterFunction ">
<div>{{ channel.name }}</div>
</div>
</body>
JS:
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.selectedFilter = "All";
vm.channelArray = [
{
name:'Channel One',
status:true
},
{
name:'Channel Two',
status:true
},
{
name:'Channel Three',
status:false
},
{
name:'Channel Four',
status:true
}
];
vm.myFilterFunction = function(value){
return (vm.selectedFilter === "All") || (!value.status);
}
});
Example Plunk

De-selecting a select all checkbox

I have a checkbox that will select all, at the moment if I press it, it will select all the the options(which is good!), then if I deselect one of them it doesn't deselect the Select All option. Any help in how to do this would be gratefully appreciated.
<span class="glyphicon glyphicon-check"></span>
<label for="sel1">Select days:</label><br />
<li>
<input type="checkbox" name="all" id="all" />
<label for='all'>Select All</label>
<ul>
<ul>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_1" value="1" />
<label for="box_1">Monday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_2" value="2" />
<label for="box_2">Tuesday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_3" value="3" />
<label for="box_3">Wednesday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_4" value="4" />
<label for="box_4">Thursday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_5" value="5" />
<label for="box_5">Friday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_6" value="6" />
<label for="box_6">Saturday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_7" value="7" />
<label for="box_7">Sunday</label>
</li>
</ul>
</ul>
</li>
</div>
Script I am currently using to Select All:
$(document).ready(function(){
$('input[name="all"],input[name="title"]').bind('click', function(){
var status = $(this).is(':checked');
$('input[type="checkbox"]', $(this).parent('li')).prop('checked', status);
});
});
$(document).ready(function){
}
Example:
http://jsfiddle.net/0e018w0y/
You're most of the way there.
I'd attach a "change" event listener to all the checkboxes, confirming that (on change) whether all the checkboxes are selected or not... (FYI you're using checkboxes and not radio buttons. Radio buttons only allow 1 to be selected at a time.)
// On change of any (not "Select All" checkbox)
$('input[name="selected[]"]').change(function () {
var selectAll = true;
// Confirm all checkboxes are checked (or not)
$('input[name="selected[]"]').each(function (i, obj) {
if ($(obj).is(':checked') === false) {
// At least one checkbox isn't selected
selectAll = false;
return false;
}
});
// Update "Select All" checkbox appropriately
$('input[name="all"]').prop('checked', selectAll);
});
In the example I've tried to follow your convention for checking if things are selected or not etc - except I've used "change()" rather than "click()" (which captures any change event, not just mouse-clicks).
Line by line:
$('input[name="selected[]"]').change(function () {
...
}
This captures the change event on all select boxes. You could use classes or a name convention to identify the checkboxes to attach it to.
var selectAll = true;
The scope of this variable reaches the nameless function provided to the .each(...) call which follows. We're using this to track whether every checkbox is checked or not.
$('input[name="selected[]"]').each(function (i, obj) {
if ($(obj).is(':checked') === false) {
// At least one checkbox isn't selected
selectAll = false;
return false;
}
});
This checks every checkbox, see if any are not checked.
Then we update the "Select All" checkbox appropriately.
Looking at it again (2 minutes later), I can see this could be reduced actually:
var allSelected = ($('input[name="selected[]"]:not(:checked)').length === 0);
// Update "Select All" checkbox appropriately
$('input[name="all"]').prop('checked', allSelected);
I've not tested if this is faster ... I've just offloaded the checking of "is checked" to jQuery itself. The "length" property returns how many elements match the criteria - ":not(:checked)" does what you'd expect, matches only the aforementioned inputs which are not checked.
If the count is not equal to 0, we deselect the "Select All" checkbox.
Example:
http://jsfiddle.net/zyxgm2kz/
Try this:
You need to bind a change listener for all the days checkbox and if all the checkboxes are checked then you can play with select all checkbox checked property.
$(document).ready(function () {
var allCB = $('input[name="selected[]"]');
var mainCB = $('input[name="all"]')
mainCB.on('click', function () {
var status = $(this).is(':checked');
allCB.prop('checked', status);
});
allCB.on('change', function () {
var status = $('input[name="selected[]"]:checked').length === allCB.length;
$('input[name="all"]').prop('checked', status);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<li>
<input type="checkbox" name="all" id="all" />
<label for='all'>Select All</label>
<ul>
<ul>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_1" value="1" />
<label for="box_1">Monday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_2" value="2" />
<label for="box_2">Tuesday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_3" value="3" />
<label for="box_3">Wednesday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_4" value="4" />
<label for="box_4">Thursday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_5" value="5" />
<label for="box_5">Friday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_6" value="6" />
<label for="box_6">Saturday</label>
</li>
<li class="moveli">
<input type="checkbox" name="selected[]" id="box_7" value="7" />
<label for="box_7">Sunday</label>
</li>
</ul>
</ul>
</li>
you can try this one:
$(document).ready(function() {
$('input[name="all"],input[name="title').click(function(event) { //on click
if(this.checked) {
$('input[type="checkbox').each(function() {
this.checked = true;
});
}else{
$('.input[type="checkbox').each(function() {
this.checked = false;
});
}
});
});
DEMO FIDDLE
$('input[name="all"],input[name="title"]').bind('click', function () {
var status = $(this).is(':checked');
$('input[type="checkbox"]', $(this).parent('li')).prop('checked', status);
});
var checkbox = $(':checkbox').not('#all');
$(checkbox).change(function () {
checkbox.each(function () {
if ($(this).is(':checked')) {
} else {
$(':checkbox#all').prop('checked', false)
}
})
})
Get the checkbox except the all then check if one is uncheck remove the check from all
DEMO

AngularJS master checkbox toggler

Is it possible with AngularJs to do: master checkbox which turn on/off it child checkboxes - each one of them showing a different content. Plunkerenter code here
Yes, you can create a master checkbox toggle. Here's a working plunkr.
View
<input type="checkbox" ng-model="selectAll" ng-click="checkAll()" />
<input type="checkbox" ng-model="checkbox[0].selected" />
<input type="checkbox" ng-model="checkbox[1].selected" />
<input type="checkbox" ng-model="checkbox[2].selected" />
Controller
// Check/uncheck all boxes
$scope.checkAll = function () {
angular.forEach($scope.checkbox, function (obj) {
obj.selected = $scope.selectAll;
});
};
add the model to the 'ng-checked' expression
<input id="checkSlave" type="checkbox" ng-checked="master || slave1" ng-model="slave1" aria-label="Slave input">
<input id="checkSlave" type="checkbox" ng-checked="master || slave2" ng-model="slave2" aria-label="Slave input">
<input id="checkSlave" type="checkbox" ng-checked="master || slave3" ng-model="slave3" aria-label="Slave input">
add 'master' into ng-show expression
<div ng-show="slave1 || master">Slave one showed!</div>
<div ng-show="slave2 || master">Slave two showed!</div>
<div ng-show="slave3 || master">Slave three showed!</div>

Possible to pass several array items using 1 attribute?

I have a group of tick boxes with 1 select all box at the top
<input type="checkbox" id="1195" value="All" />
<input type="checkbox" name="GroupA" title="TickboxA" value="TickboxA" id="TickboxA" />
<input type="checkbox" name="GroupA" title="TickboxB" value="TickboxB" id="TickboxB" />
<input type="checkbox" name="GroupA" title="TickboxC" value="TickboxC" id="TickboxC" />
<input type="checkbox" name="GroupA" title="TickboxD" value="TickboxD" id="TickboxD" />
I'm passing all the checks to an array so I can pass it around the site like so:
$('input').on('ifClicked', function (event) {
addRemoveService(document.getElementById(this.title));
setItemArray();
document.getElementById('mydoc').value = "";
for (var i = 0; i < itemIdArray.length; i++) {
setInterestedIn(i);
}
});
I have some jquery that will tick all the boxes for me if i click on the top checkbox - Everything is working perfect, except if i tick on the 'all' checkbox - I can't pass all the titles of all the other boxes to the array - what I want to do is something like:
<input type="checkbox" id="1195" value="All" title="TickboxA,TickboxB,TickboxC,TickboxD" />
If that makes sense? Is there an easy way to do this?

jQuery Validation Plugin Multiple Checkboxes

I am having some difficulty in using the jQuery Validator plugin. I have a list of checkboxes with different name attributes and I can't seem to figure out how to ensure that at least one of them has been checked. Everything that I find on Google seems to only work when the name attribute is the same.
Here is some sample code (updated):
<ul id="email_lists">
<li>
<input name="checkbox1" type="checkbox" /> List 1
</li>
<li>
<input name="checkbox2" type="checkbox" /> List 2
</li>
<li>
<input name="checkbox3" type="checkbox" /> List 3
</li>
<li>
<input name="checkbox4" type="checkbox" /> List 4
</li>
</ul>
I want to make sure that at least one of those is checked. Unfortunately, I cannot make the names the same as it is form that submits to a third-party email marketing application and it is expecting specific name attributes for these checkboxes.
Update
I am aware of how to do this using plain jQuery, but I would prefer to use the jQuery Validator plugin since that is how all of the other validation on the page is done.
I can group those checkboxes using jQuery by saying $('#email_lists li');, but I'm not really sure how to use something like that and tell the jQuery Validator plugin to use that as a group.
Assuming that you can give the checkboxes a class name (the jQuery needs something to work with):
<input class="validationGroupOne" name="checkbox1" type="checkbox" />
<input class="validationGroupOne" name="checkbox2" type="checkbox" />
<input class="validationGroupOne" name="checkbox3" type="checkbox" />
<input class="validationGroupOne" name="checkbox4" type="checkbox" />
You should be able to plug in the .validationGroupOne class-selector in place of the, usual, name attribute.
This was my solution :-)
Use:
<div id="list">
<input name="chkbox" type="checkbox" />
<input name="chkbox" type="checkbox" />
<input name="chkbox" type="checkbox" />
<input name="chkbox" type="checkbox" />
</div>
<input type="hidden" name="the_real_field_name" />
Then in jquery validate plugin block:
rules : {
chkbox: "required"
},
Then store the values as an array into a single hidden field like:
function updateInput() {
var allVals = [];
$('#list :checked').each(function() {
allVals.push($(this).val());
});
$('#the_real_field_name').val(allVals);
}
$(function() {
$('#list input').click(updateInput);
updateInput();
});

Categories

Resources