Check-all checkbox is not changes object properties from select - angularjs

My Code - Plunker
I'm trying to changes status of all my list objects by using a master checkbox that
checks all objects and changes their properties by selecting the required status from the
select element.
The problem is that when I'm trying to apply change on all elements by using the "Check All" 'checkbox' it is not working.
e.g.
When I check manually all the checkboxes without using the master checkbox it is working.
My Code
var webApp = angular.module('webApp', []);
//controllers
webApp.controller ('VotesCtrl', function ($scope, Votes) {
$scope.votes = Votes;
$scope.statuses = ["Approved","Pending","Trash","Spam"];
$scope.expand = function(vote) {
console.log("show");
$scope.vote = vote;
$scope.ip = vote.ip;
$scope.date = vote.created;
};
$scope.change = function() {
for(var i = 0; i < $scope.votes.length; i++) {
if($scope.votes[i].cb) {
$scope.votes[i].status = $scope.votes.status;
$scope.votes[i].cb = false;
}
$scope.show = false;
}
};
});
//services
webApp.factory('Votes', [function() {
//temporary repository till integration with DB this will be translated into restful get query
var votes = [
{
id: '1',
created: 1381583344653,
updated: '222212',
ratingID: '3',
rate: 5,
ip: '198.168.0.0',
status: 'Pending',
},
{
id: '111',
created: 1381583344653,
updated: '222212',
ratingID: '4',
rate: 5,
ip: '198.168.0.1',
status: 'Spam'
},
{
id: '2',
created: 1382387322693,
updated: '222212',
ratingID: '3',
rate: 1,
ip: '198.168.0.2',
status: 'Approved'
},
{
id: '4',
created: 1382387322693,
updated: '222212',
ratingID: '3',
rate: 1,
ip: '198.168.0.3',
status: 'Spam'
}
];
return votes;
}]);
My HTML
<body ng-controller='VotesCtrl'>
<div>
<ul>
<li class="check" ng-click=>
<input type="checkbox" ng-model="master"></input>
</li>
<li class="created">
<a>CREATED</a>
</li>
<li class="ip">
<b>IP ADDRESS</b>
</li>
<li class="status">
<b>STATUS</b>
</li>
</ul>
<ul ng-repeat="vote in votes">
<li class="check">
<input type="checkbox" ng-model="vote.cb" ng-checked="master"></input>
</li>
<li class="created">
{{vote.created|date}}
</li>
<li class="ip">
{{vote.ip}}
</li>
<li class="status">
{{vote.status}}
</li>
</ul>
</div>
<br></br>
<div class="details">
<h3>Details:</h3>
<div>DATE: {{date|date}}</div>
<div>IP: {{ip}}</div>
<div>STATUS:
<select ng-change="change()" ng-init="votes.status='Approved'"
ng-model="votes.status"
ng-options="status for status in statuses">
</select>
<p>{{vote.status|json}}</p>
</div>
</div>
</body>
Why is master checkbox not working?

I changed your method change a bit to make it work.
From Plunker you can see that on master change all children still have old value. So I added onMasterChange method
HTML
<input type="checkbox"
ng-model="master"
ng-change="onMasterChange(master)"></input>
I created as default: $scope.master = false;
....
$scope.master = false;
$scope.onMasterChange = function(master){
for(var i = 0; i < $scope.votes.length; i++) {
$scope.votes[i].cb = master;
}
};
$scope.change = function(value) {
for(var i = 0; i < $scope.votes.length; i++) {
//if($scope.votes[i].cb == undefined){
// $scope.votes[i].cb = false;
// }
if($scope.master == true){
$scope.votes[i].cb = $scope.master;
$scope.votes[i].status = value;
}
else if( $scope.votes[i].cb == true) {
$scope.votes[i].status = value;
}
}
};
See Plunker
Hope it will help,

It is working, but I believe ng-model is taking precedence over ng-checked. If you remove ng-model from the checkboxes, ng-checked is working as expected.
<input type="checkbox" ng-checked="master"></input>
http://plnkr.co/edit/q35JlhOVSGxmu6QW8e98?p=preview
It is important to note, however, that ng-checked does not update your model, it only changes the presentation of the checkbox. A way of tackling this would be to remove the master binding, and call a method with ng-click on your master checkbox which changes .cb on each box.
Edit: Working version using a watch on the master checkbox.
http://plnkr.co/edit/3NwGtp1FX8g9bfMrbWU5?p=preview

Related

How to programmatically check checkbox with dynamic model name?

I have created a some checkboxes with dynamic model name like this:
<label ng-repeat="item in main.itemDetails">
<input type="checkbox" checklist-value="item.price"
ng-click="itemChanged(item)" ng-model="checkboxes[item.name]">
{{item.name}} - <b>{{item.price}} €</b>
<br>
</label>
In my controller, I want to check some checkboxes if their model's name exists in array $scope.selectedItems.
I'm trying to do something like this but it isn't working:
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope['selectedItems[i].name'].isChecked = true;
}
for example if item.name = 'Item1' I want the model to be named $scope.Item1 and later I want to call $scope.Item1.isChecked = true;
What Am I doing wrong here?
Your are storing the model in the $scope.checkboxes, so you can set its value to true like the code below.
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope.checkboxes[$scope.selectedItems[i].name] = true;
}
It looks like your using a string literal here:
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope['selectedItems[i].name'].isChecked = true;
}
Just change this to read:
for (var i = 0, j = $scope.selectedItems.length; i<j; i++) {
$scope[selectedItems[i].name].isChecked = true;
}
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.main = [{
'name':'test1',
'price':'23',
'isChecked':false
},
{
'name':'test2',
'price': '25',
'isChecked':false
},
{
'name':'test3',
'price': '21',
'isChecked':false
}];
$scope.selectedItems = [{
'name':'test1'
},
{
'name':'test2'
}];
angular.forEach($scope.main, function(valueMain){
angular.forEach($scope.selectedItems,function(valueSelected){
if(valueMain.name=== valueSelected.name){
valueMain.isChecked = true;
}
})
});
$scope.toggleCheck = function(item){
if(item.isChecked === true){
item.isChecked === false;
}else{
item.isChecked === true;
};
}
}
<script src="https://code.angularjs.org/angular-1.0.1.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<label ng-repeat="item in main">
<input type="checkbox" ng-model="item.isChecked" ng-checked="item.isChecked" ng-change="toggleCheck(item)">
{{item.name}} - <b>{{item.price}} €</b>
<br>
</label>
</div>
</div>
Angular Foreach is the easiest way to solve this kind of problem.

Ionic toggle group check one item and uncheck the others

I have created a toggle view to select available items in Ionic, and if anyone of the item were selected, I want to uncheck all the other items. I also have a scan function which allows me to dynamically update the items list
I'm fairly new to ionic, so I just have the following code in my settings.html
<ion-toggle ng-repeat="item in itemsList"
ng-model="item.checked">
{{ item.text }}
</ion-toggle>
and then I have created a simple settings.js:
(function () {
'use strict';
angular.module('i18n.setting').controller('Settings', Settings);
SettingController.$inject = ['$scope'];
function Settings($scope){
$scope.settingsList = [
{text: "item1", checked: true},
{text: "item2", checked: false}
];
}
})();
I know ng-model="item.checked" will do the job of changing the attribute $scope.settingsList.checked for me. But what I want to know this how to use it to check one items and uncheck all the other ones?
loop through all the items, set the checked state of all the values to false and then your html code must be:
<ion-toggle ng-repeat="item in settingsList"
ng-model="item.checked"
ng-checked="item.checked" style="border:1px solid #28a54c" ng-change="toggleChange(item)">
{{ item.text }}
</ion-toggle>
Your Controller code
$scope.toggleChange = function(item) {
if (item.checked == true) {
for(var index = 0; index < $scope.settingsList.length; ++index)
$scope.settingsList[index].checked = false;
item.checked = true;
} else {
item.checked = false
}
};
And it's better to use forEach in async environment.
Angular 2+ Version, Ionic 4
HTML
<div class="toogle" *ngFor="let item of toogleConfig">
<div class="toogle__title">{{item.title}}</div>
<ion-toggle [(ngModel)]="item.checked" (ngModelChange)="ToogleChange(item.id)" color="success"></ion-toggle>
</div>
</div>
TS
public toogleConfig = [
{id:0, title:'Recurrent', checked: false},
{id:1, title:'One time', checked: false},
]
public ToogleChange(index:number) {
this.toogleConfig.forEach(toogle => { toogle.checked = false; });
this.toogleConfig[index].checked = true;
}

check a checkbox by clicking a link in angularJs

I have the folowing code :
<li ng-repeat="item in items">
<a href="#" ng-if="!item.children" ng-click="checkItem(item,checkBoxModel)">
<input class="align"
ng-click="checkItem(item,checkBoxModel)"
type="checkbox" ng-checked="master"
ng-model="checkboxModel"/>
{{ item.title }}
</a>
</li>
in my controller i have checkItem function:
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
$scope.master=true;
$scope.checkBoxModel = false;*
} else {
....
$scope.master = false;
$scope.checkBoxModel = true;
}
}
The problem is that when I click on a link all of the checkboxes are checked. I just want the checkbox associated to the link to be checked.
Instead of setting a value master on the controllers $scope object, set it on the actual item that you pass in, and set it's ng-checked="item.master" and it's ng-model="item.checkBoxModel"
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
item.master=true;
item.checkBoxModel = false;
} else {
....
item.master = false;
item.checkBoxModel = true;
}
}
Change your app logic. You have to declare a variable for each item. But as i see, you have one for all in the global $scope named master. The master should have been declared for each item to specify the state of the option box. Then your problem will be solved.
Something like this:
app.js
$scope.items = [
{
name: 'example',
master: false,
checkboxModel: false
},
{
name: 'example',
master: false,
checkboxModel: false
}
];
$scope.checkItem = function(item, checkBoxModel) {
if (checkBoxModel == undefined || checkBoxModel == true) {
....
$scope.items[item].master = true;
...
} else {
....
$scope.items[item].master = false;
...
}
}
index.html
<input class="align"
ng-click="checkItem(item, checkBoxModel)"
type="checkbox" ng-checked="item.master"
ng-model="item.checkboxModel"/>
<li ng-repeat="item in items">
<a href="#" ng-if="!item.children" ng-click="checkItem(item)">
<input class="align"
ng-click="checkItem(item)"
type="checkbox" ng-checked="item.checked"
/>
{{ item.title }}
</a>
in my controller i change the value of item.checked

Angular-xeditable: Need a checklist that displays checked items

I would like to use a check list and show the user the boxes she has checked.
I am using this framework: http://vitalets.github.io/angular-xeditable/#checklist . See his example 'Checklist' versus his example 'Select multiple'. However, I do not want to display a link with a comma separated string, i.e., join(', '). I would like each selection to appear beneath the previous, in an ordered list or similar.
Pretty much copied from his examples, here are the guts of my controller:
$scope.userFeeds = {
feeds: {}
};
$scope.feedSource = [
{ id: 1, value: 'All MD' },
{ id: 2, value: 'All DE' },
{ id: 3, value: 'All DC' }
];
$scope.updateFeed = function (feedSource, option) {
$scope.userFeeds.feeds = [];
angular.forEach(option, function (v) {
var feedObj = $filter('filter')($scope.feedSource, { id: v });
$scope.userFeeds.feeds.push(feedObj[0]);
});
return $scope.userFeeds.feeds.length ? '' : 'Not set';
};
And here is my html:
<div ng-show="eventsForm.$visible"><h4>Select one or more feeds</h4>
<span editable-select="feedSource"
e-multiple
e-ng-options="feed.id as feed.value for feed in feedSource"
onbeforesave="updateFeed(feedSource, $data)">
</span>
</div>
<div ng-show="!eventsForm.$visible"><h4>Selected Source Feed(s)</h4>
<ul>
<li ng-repeat="feed in userFeeds.feeds">
{{ feed.value || 'empty' }}
</li>
<div ng-hide="userFeeds.feeds.length">No items found</div>
</ul>
</div>
My problem is - display works with editable-select and e-multiple, but not with editable-checklist. Swap it out and nothing is returned.
To workaround, I have tried dynamic html as in here With ng-bind-html-unsafe removed, how do I inject HTML? but I have considerable difficulties getting the page to react to a changed scope.
My goal is to allow a user to select from a checklist and then to display the checked items.
Try this fiddle: http://jsfiddle.net/mr0rotnv/15/
Your onbeforesave will need to return false, instead of empty string, to stop conflict with the model update from xEditable. (Example has onbeforesave and model binding working on the same variable)
return $scope.userFeeds.feeds.length ? false : 'Not set';
If you require to start in edit mode add the attribute shown="true" to the surrounding form element.
Code for completeness:
Controller:
$scope.userFeeds = {
feeds: []
};
$scope.feedSource = [
{ id: 1, value: 'All MD' },
{ id: 2, value: 'All DE' },
{ id: 3, value: 'All DC' }
];
$scope.updateFeed = function (feedSource, option) {
$scope.userFeeds.feeds = [];
angular.forEach(option, function (v) {
var feedObj = $filter('filter')($scope.feedSource, { id: v });
if (feedObj.length) { // stop nulls being added.
$scope.userFeeds.feeds.push(feedObj[0]);
}
});
return $scope.userFeeds.feeds.length ? false : 'Not set';
};
Html:
<div ng-show="editableForm.$visible">
<h4>Select one or more feeds</h4>
<span editable-checklist="feedSource"
e-ng-options="feed.id as feed.value for feed in feedSource"
onbeforesave="updateFeed(feedSource, $data)">
</span>
</div>
<div ng-show="!editableForm.$visible">
<h4>Selected Source Feed(s)</h4>
<ul>
<li ng-repeat="feed in userFeeds.feeds">{{ feed.value || 'empty' }}</li>
<div ng-hide="userFeeds.feeds.length">No items found</div>
</ul>
</div>
Css:
(Used to give the "edit view" a list appearance)
.editable-input label {display:block;}
Also there is the option of using a filter if you do not need to do any validation or start in edit mode.
Controller:
$scope.user = { status: [2, 3] };
$scope.statuses = [
{ value: 1, text: 'status1' },
{ value: 2, text: 'status2' },
{ value: 3, text: 'status3' }
];
$scope.filterStatus = function (obj) {
return $scope.user.status.indexOf(obj.value) > -1;
};
HTML:
<a href="#" editable-checklist="user.status" e-ng-options="s.value as s.text for s in statuses">
<ol>
<li ng-repeat="s in statuses | filter: filterStatus">{{ s.text }}</li>
</ol>
</a>

AngularJS checkbox filter directive

I have a AngularJS directive that allows users to select a values from a list to filter on. Pretty simple concept which is represented here:
Problem is when I click one of the checkboxes they all select unintended. My directive is pretty simple so I'm not sure why this is happening. The code around the selection and checkboxes is as follows:
$scope.tempFilter = {
id: ObjectId(),
fieldId: $scope.available[0].id,
filterType: 'contains'
};
$scope.toggleCheck = function (id) {
var values = $scope.tempFilter.value;
if (!values || !values.length) {
values = $scope.tempFilter.value = [];
}
var idx = values.indexOf(id);
if (idx === -1) {
values.push(id);
} else {
values.splice(idx, 1);
}
};
$scope.valuesListValues = function (id) {
return $scope.available.find(function (f) {
return f.id === id;
}).values;
};
and the data resembles:
$scope.available = [{
id: 23,
name: 'Store'
values: [
{ id: 124, name: "Kansas" },
{ id: 122, name: "Florida" }, ... ]
}, ... ]
the view logic is as follows:
<ul class="list-box">
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
<div class="checkbox">
<label ng-click="toggleCheck(val.id)">
<input ng-checked="tempFilter.value.indexOf(val.id) === -1"
type="checkbox"> {{val.name}}
</label>
</div>
</li>
</ul>
First off, it toggleCheck fires twice but populates the correct data ( second time given my code it removes it though ).
After the second fire, it checks all boxes... Any ideas?
Perhaps its that the local variable doesn't get reassigned to the property of the scope property used in the view. Since your values are then non-existent and not found, the box is checked.
$scope.tempFilter.value = values
I took the interface concept you were after and created a simpler solution. It uses a checked property, found in each item of available[0].values, as the checkbox model. At the top of the list is a button that clears the selected items.
JavaScript:
function DataMock($scope) {
$scope.available = [{
id: 23,
name: 'Store',
values: [{
id: 124,
name: "Kansas"
}, {
id: 122,
name: "Florida"
}]
}];
$scope.clearSelection = function() {
var values = $scope.available[0].values;
for (var i = 0; i < values.length; i++) {
values[i].checked = false;
}
};
}
HTML:
<body ng-controller="DataMock">
<ul class="list-box">
<li>
<button ng-click="clearSelection()">Clear Selection</button>
</li>
<li ng-repeat="val in available[0].values">
<div class="checkbox">
<label>
<input ng-model="val.checked"
type="checkbox" /> {{val.name}}
</label>
</div>
</li>
</ul>
</body>
Demo on Plunker
The repeat that I used to grab the values based on the id, was the problem area.
<li ng-repeat="val in valuesListValues(tempFilter.fieldId)">
removing that and simple listening and setting a static variable resolved the problem.
$scope.$watch('tempFilter.fieldId', function () {
var fId = $scope.tempFilter.fieldId;
if ($scope.isFieldType(fId, 'valuesList')) {
$scope.valuesListValues = $scope.valuesListValues(fId);
}
}, true);
});
and then in the view:
ng-repeat="value in valuesListValues"

Resources