sub ng-repeats, getting (checked) checkbox values in angular - javascript

I have some nested ng-repeats I am working with and the third level down is a grouping of checkboxes. Initially I am sent an array of options for the checkboxes so I do this:
<div class="fadingOptionsHere" ng-repeat="fading in fade.options">
<input type="checkbox" ng-model="fadingsHere" value="{{fading.id}}">{{fading.name}}
</div>
I am tyring to find a way to ONLY get the values of the selected checkboxes back. It would be super ideal if I could just replace the nested options array with an array of only the selected items, so I could just send the json object back like that.
This is the third level down of nesting so I'm having trouble tracking these guys. How would I be able to get only the selected values (as the fading.id) of the select boxes for each iteration of the ng-repeat?
I keep trying to reference the fadingsHere model with no success.
Thanks!

You can do this in this way.
In HTML do like below.
<ul>
<li data-ng-repeat="record in records">
<input type="checkbox" ng-model="selected[record.Id]"> {{record.Id}}
</li>
</ul>
And in controller you have to add selected property.
function MyCtrl($scope) {
$scope.records = [ { "Id": 1, }, { "Id": 2 }, { "Id": 3 } ];
$scope.selected = {};
$scope.ShowSelected = function() {
return $scope.selected
};
When you read the selected property you will get the selected list.
Demo

you could use checklist model directive like
<input type="checkbox" class="form-control"
checklist-model="transaction.jobData[attribute.key]"
checklist-value="checkBoxAttributes.code">

Related

Display checkboxes in with AngularJS based on two object arrays

I know there are several similar topics already but I found none that really matches my problem.
When opening my AngularJS app/website I am loading two arrays of objects (both are of the same type). One list contains all possible values (called sources here) and the other list is a selection of elements from the first.
My goal is display all sources as checkboxes. The ones from the second list have to be preselected, the rest not. Now the user can select/deselect checkboxes. If he does so I need to inform the server (with the source.id).
What I got so far:
exampleApp.controller('testController', [ '$scope', '$http', function($scope, $http) {
$scope.sources = [];
$scope.selectedSources = [];
$scope.changeSource = function(source) {...};
})
and
<div ng-repeat="source in sources">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="??"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
What I can't figure out is how I can get ng-model to preselect the right checkboxes and how to get the new (and old) values to changeSource(). Is there an elegant way of doing that?
Example (Pseudo code only):
Sources = [{id=1, name=test1},{id=2, name=test2}, ...]
SelectedSources = [{id=2, name=test2}]
Now what I need are checkboxes like this:
[ ] test1 [x] test2
where all elements from sources are checkboxes and the ones from selectedsources are preselected. Changes of the selection can be stored in selected sources (as objects) and have to trigger my changeSource() function so that I can inform my server.
Set the selected/unselected state in a property inside each of the objects in Sources array(initialize it based on whats present in selectedArray)
$scope.sources.forEach(function(source) {
source.selected = isSelected(source);
})
function isSelected(selectedSource) {
return !!$scope.selectedSources.find(function(s) {
return s === selectedSource || s.id == selectedSource.id;
})
}
Here's a working plunker link
I didn't understood your question very well, but if i'm not mistaken, you want to fill the second collection only with the selected items from the first one, right? If it's the case, you could turn your second collection into a returning function with a filter of the first inside, as follows:
In your controller:
exampleApp.controller('testController', [ '$scope', '$http', function ($scope, $http) {
$scope.sources = [];
/* ... */
$scope.getSelectedSources = function () {
return $scope.sources.filter(function (val) {
return val.selected;
});
};
})
In your template:
<div ng-repeat="source in sources">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="source.selected"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
<div ng-repeat="source in getSelectedSources()">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="source.selected"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
Hi this may be help you to get new & old value.
$scope.$watch('sources', function (oldval, newval) {
console.log(oldval + newval);
});

All the checkboxes inside a ng-repeat are getting checked when I select just one

I have list of objects named rolePermissionList like this:
[{"id":1,"name":"createUser","type":"user","marked":1},{"id":2,"name":"deleteUser","type":"user","marked":1},{"id":3,"name":"editRole","type":"role","marked":0}]
and I use ng-repeat to repeat checkboxes using the values in that list like this
<div class="form-group">
<label>Role Permissions:</label>
<div class="checkbox" ng-repeat="permission in rolePermissionList">
<label>
<input type="checkbox" ng-model="idsPermission[permission .idPermission ]"
ng-checked="permission.checked">{{permission.name}}
</label>
</div>
</div>
the ng-model of the checkboxes is named idsPermission and it's a list of numbers, those numbers are the IDS of the objects.
When I load the page the checkboxes that are supposed to be checked are checked this part works fine, but when I check another checkbox all the checkboxes gets checked, and when I uncheck a checkbox the same thing happens all the checkboxes gets unchecked.
I use that list of numbers named idsPermission to get all the IDS of the checkboxes that are checked, this worked before I used the directive ng-checked="permission.checked", but now I need to use it since now I need to show the checkboxes that are already marked.
this is my controller
angular.module('MyApp')
.controller('RolCtrl', ['$scope', 'RolService',
function ($scope, RolService) {
$scope.idsPermission = {};
$scope.getListCheckBoxesEditRole = function (idRole) {
$scope.selectRol.descripcion;
RolService.getListCheckBoxesEditRole(idRole)
.then(
function (d) {
var userPermissionList = [];
for (var permission in d) {
if (d[permission ].type === 'user') {
if (d[permission ].marked === 1)
{
d[permission ].checked = true;
userPermissionList.push(d[permission ]);
} else {
userPermissionList.push(d[permission ]);
}
}
}
$scope.rolePermissionList = userPermissionList;
},
function (errResponse) {
console.error('ERROR');
}
);
};
}
$scope.getListCheckBoxesEditRole(3);
]);
The RolService.getListCheckBoxesEditRole(idRole) service returns this JSON [{"id":1,"name":"createUser","type":"user","marked":1},{"id":2,"name":"deleteUser","type":"user","marked":1},{"id":3,"name":"editRole","type":"role","marked":0}]
and what I do in the controller is iterate over that list and check if the marked field is 1 if it's 1 I do this d[permission ].checked = true; I what I think that I do in that line is setting the checked value to true so I could use this directive in the html view ng-checked="permission.checked"
I tried doing this ng-checked="idsPermission[permission.checked]" but when I do this the values that are marked=1 in the JSON that I paste above don't appear checked when I load the page, but if I put it like this ng-checked="permission.checked" they appear marked as they should, but when I click a checkbox all the checkboxes gets selected.
I came across too many issues to document but the main problem was how you are iterating through the array that is returned from the service. It should be something like this:
Controller
angular.forEach(d.data, function(permission) {
if (permission.type === 'user') {
if (permission.marked === 1) {
permission.checked = true;
userPermissionList.push(permission);
} else {
userPermissionList.push(permission);
}
}
});
Then you can simplify your html like this:
HTML
<input type="checkbox" ng-model="permission.checked" />
You can see all of the changes in this working plunk.
I can't see in your code that $scope.idsPermission is getting defined. In ng-repeat you only set the key for the object but the value is undefined. That's why the checkbox won't show the correct value.
You could use ng-init to initialize the model. Please have a look at the simplified demo below or this fiddle.
(Also defining the models in your controller would be possible.)
Only using ng-model should be enough for the checkbox to work. I think I've read somewhere that ng-checked and ng-model aren't working smoothly together.
angular.module('demoApp', [])
.controller('mainCtrl', MainCtrl);
function MainCtrl() {
var vm = this;
angular.extend(vm, {
data: [{
id: 0,
marked: 1
}, {
id: 1,
marked: 0
}, {
id: 2,
marked: 1
}]
})
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainCtrl as ctrl">
<div ng-repeat="item in ctrl.data">
<input type="checkbox" ng-init="ctrl.idPermissions[item.id] = !!item.marked" ng-model="ctrl.idPermissions[item.id]"/>{{item.id}}
</div>
<pre>
permissions: {{ctrl.idPermissions | json: 2}}
data{{ctrl.data | json: 2}}</pre>
</div>

Parsing JSON result to object by using checkbox

I have loaded a JSON list into a table and I would like to parse 1 JSON result or multiple results into an object, so I can send it to the server.
My table looks like this so far:
HTML
<tr ng-repeat="t in student">
<td ng-model="herkanserNaam">{{ t.Name }}</td>
<td>{{ t.City }}</td>
<td>
<div class="checkbox" ng-click="laatzien(herkanserNaam, herkanserCheck)" ng-model="herkanserCheck">
<label>
<input type="checkbox">
</label>
</div>
</td>
</tr>
Controller
$scope.laatzien = function(name, active) {
var herkanser = [{
"name" : name,
"active" : false
}];
console.log(herkanser);
}
How would I be able to check one or multiple results and save the data(t.Name) into an object by using a checkbox? So far the function laatzien() is returning the empty values defined in herkanser.
The reason your laatzien method is failing is due to how you are using your directives. Let's work with the example you provided to get your laatzien method to fire.
HTML
<tr ng-repeat="student in students">
<td>{{ student.Name }}</td>
<td>{{ student.City }}</td>
<td>van</td>
<td>Huis</td>
<td>j.huis#student.han.nl</td>
<td>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="student.isActive" ng-change="laatzien(student)">
</label>
</div>
</td>
</tr>
Javascript
$scope.laatzien = function (student) {
var herkanser = [{
"name": student.name,
"active": student.isActive
}];
console.log(herkanser);
}
I have made some opinionated changes in your example for readability purposes, others were needed to get the directives to fire as expected. Below are the changes to your snippets.
Renamed the student array to students. This will require a change in your controller from $scope.student to $scope.students.
Renamed the t object to student.
Removed the ng-click directive from your div.
Added an ng-change directive on your checkbox. Now when you click the checkbox your laatzien method should fire.
Added an isActive property to your student. Inside of your laatzien method, you may now check the state of the checkbox. If the checkbox is checked, student.isActive = true. If the checkbox is not checked, student.isActive = false.
From your code, you seem to want to build the "list of checked students" and send that to the server. In other words, what you want, is to allow the user to check on multiple students and at the end collect everything that was checked and send it over to the server.
If that's the case then your strategy to put an ng-click over the checkbox is wrong.
What you need is to bind your checkbox to your $scope model. Such as this:
<input type="checkbox" ng-model="t.isChecked" ng-true-value="true" ng-false-value="false'">
When the user checks the checkbox for a student. Your model will automatically be updated.
To collect the data to send over the server you need to put an ng-click on a submit button. In the event handler, simply loop through every student in your $scope "students" model and only save the ones that have isChecked property to true to be sent over to the server.
Hope this helps!
You could make a function to push thet item into an obj like so...
$scope.students = [
{
"name":"John",
"city":"Boston"
},
{
"name":"Amy",
"city":"Dallas"
}
]
$scope.activeObj = [];
$scope.laatzien = function(obj) {
if($.inArray(obj, $scope.activeObj) == -1) {
$scope.activeObj.push(obj);
} else {
var index = $scope.activeObj.indexOf(obj);
$scope.activeObj.splice(index, 1);
}
}
http://jsfiddle.net/5fcnazb2/

How to initialize ng-model of input checkboxes in an ng-repeat loop

I've run into an issue when creating multiple input[checkbox]es for a list of items in angular with ng-repeat and attaching an ng-model:
<li ng-repeat="item in items">
<a ng-href="#/{{item.id}}" > {{ item.id }} </a>
<input type="checkbox" ng-model="selectedMessages[item.id]"/>
</li>
The issue here is that selectedMessages[item.id] is only initialized and set when the checkbox is clicked once.
The reason this is necessary is that I would like to toggle all checkboxes with a single comand like so:
$scope.toggleCheckboxes = (state) ->
for key, val of $scope.selectedMessages
$scope.selectedMessages[key] = state # true or false
Let's say I have 3 checkboxes, and click 1 once, 2 twice, and 3 never, then said object will look like this:
$scope.selectedMessages = {
"1" : true,
"2" : false
}
So obviously, $scope.toggleCheckboxes(true) will only work for those checkboxes.
Is there a good way to initialize this ng-model for multiple checkboxes?
You can use ng-init to populate the array. I used $index rather than making up a bunch of data with id properties...adjust your code accordingly
<input type="checkbox"
ng-model="selectedMessages[$index]"
ng-init="selectedMessages[$index]=selectedMessages[$index]||false" />
JS
$scope.selectedMessages=[];
$scope.checkAll=function(){
var msgs = $scope.selectedMessages
msgs.forEach(function(elem, idx){
msgs[idx] =true
})
}
DEMO

angularJs - Is it possible for 2 different models of different structures to sync or share states?

I have a list of checkboxes and values I"m loading from a list which comes back from the database.
Controller
listA = ['item1','item2'...'itemn']; //Master list of items
$scope.selectedItems = ["item1",... "item5"]; //selected items
$scope.attributesModel = [ //new model based on selected items
{"index":5,"attribute":"item1"},
{"index":10, "attribute":"item2"},
{"index":13, "attribute":"item3"},
{"index":21, "attribute":"item4"},
{"index":24, "attribute":"item5"}
];
View part 1
<td>
<div class="checkbox checkbox-notext">
<input checklist-model="selectedItems" checklist-value="key" type="checkbox" id="{{key}}" ng-disabled="exceededLimit && !checked" />
</div>
</td>
<td>
<label for="{{key}}">{{key}}{{$index}}</label>
</td>
view part 2
<div ng-repeat="(index, row) in attributesModel" >
<div class="margin10">
<div>Index<input ng-model="row.index" value="row.index" type="number" class="indexInputs"></input>{{row.attribute}}</div>
</div>
</div>
Now I would like to sync $scope.selectedItems and $scope.attributesModel. When a checkbox is deselected, both selectedItems and attributesModel models remove that item, and vice versa. So every time someone checks a new checkbox they are presented a attributesModel with an empty text field to type the index value.
catch The index key is null initially for every newly selected item that is added to attributesModel. The user must enter a new index # once the new item is created.
I've tried using watch but the problem I run into is when a new item is selected, I don't have access to the item itself. I only have access to the list without any idea whether the new item is X or if the item removed is Y in order to push/delete the right item.
So this might be a watch solution that I'm missing.
Let me know if I can clarify anything.
I am not sure what the problem is, but you could use ngChange on the checkboxes:
<input type="checkbox" ... ng-change="..." />
I asdume you have a checklist directive or something, so should do something there, but (since you don't share it with us) I can't tell what exactly :)
UPDATE:
Since the checklist directive is an external dependency, you could handle the ng-chage in your code:
<input type="checkbox" ... ng-change="changed(key)" />
/* In the controller: */
...
$scope.changed = function (key) {
if ($scope.selectedItems.indexOf(key) === -1) {
// The checkbox for `key` was unchecked...
} else {
// The checkbox for `key` was checked...
}
};

Categories

Resources