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/
Related
I currently have a table listing jobs. Each job has a checkbox.
<form name="jobsSampleSelectForm" id="jobs-sample-select-form">
<div jobs="data">
<div ng-form="jobsSampleSelectForm">
<table ng-table="tableParams" class="table" show-filter="true">
<tr ng-repeat="job in $data" class="table-highlight" ng-class="{deactivated: job.is_active == 'No'}">
<td data-title="'Sample'"><input type="checkbox" ng-model="job.selected"></td>
<td data-title="'QC ID'" sortable="'id'">{{job.id}}</td>
<td data-title="'Date Submitted'" sortable="'dateJob'">{{job.dateJob}}</td>
</tr>
</table>
</div></div>
<button type="submit" class="btn btn-primary-red" ng-click="sampleJobs()" ng-disabled="(jobs | filter: job.selected != true).length <= 0">Sample Jobs</button>
</form>
This allows the user to select the jobs they want. However, when the user sorts a column the checkbox will uncheck itself. This seems to be a common issue, so from the advice from this SO question I added a selected attribute to each job in my controller.
jobsService.getJobsByStatuses(["pre_sampling", "sampling", "setup"])
.success(function(data){
data.forEach(function(job){ job.selected = false; });
$scope.jobs = data;
var filteredData = params.filter() ? $filter('filter')(data, params.filter()) : data;
var orderedData = params.sorting() ? $filter('orderBy')(filteredData, params.orderBy()) : data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
params.total(orderedData.length);
})
This did not seem to cause a difference. What am I missing?
I created a Fiddle to show the basic idea. When the user selects checkboxes, then sorts, the checkboxes become unchecked.
just change
<td data-title="'Sample'"><input type="checkbox" ng-model="job.selected"></td>
to
<td data-title="'Sample'"><input type="checkbox" ng-model="user.selected"></td>
If you want to persist the row selection then you should bind the checkbox to user.selected instead of binding to job.selected.
If you use user.selected for ng-model each row will have its own user object with selected property binded to checkbox so that you will get the selection even after the sorting
see the updated fiddle
<input type="checkbox" ng-model="user.selected">
Working fiddle http://jsfiddle.net/PQvQ2/83/
You are not capturing the checkbox value anywhere. In the user object, you already have "selected" to capture the selection. Using the same will store the selection. If you are using a different object "job", you will capture the index of selection but it will not be mapped to the correct value. Since, "job" object only store the checkbox selected, nothing more.
The issue was that I was calling getData every time a filter was applied. This was setting my selected attribute on each job to false. To fix this issue, I moved my code to get the data outside of the getData function.
Here in my form, I am using two radio buttons and would like to check the selected values. But this does not work as expected. I would like to determine the individual radio selection value and display Big/Small in the Result column
<div ng-controller="CityCtrl">
<table>
<tr>
<th>Name</th>
<th>Big</th>
<th>Small</th>
<th>Result</th>
</tr>
<tr ng-repeat="city in cities">
<td>{{ city.name }}</td>
<td>
<input type="radio" name="{{city.name}}-{{$index}}" ng-model="big" value="big_value" ng-change="check(city.name, big)">
</td>
<td>
<input type="radio" name="{{city.name}}-{{$index}}" ng-model="small" value="small_value" ng-change="check(city.name, small)">
</td>
<td>***</td>
</tr>
</table>
</div>
Controller:
var myApp = angular.module('cityApp', []);
function CityCtrl($scope) {
$scope.big = '';
$scope.small = '';
$scope.cities = [{
id: 1,
name: 'Tokyo'
}, {
id: 2,
name: 'Guangzhou'
}, {
id: 3,
name: 'Seoul'
}];
$scope.check = function(city, value) {
console.log("City->" + city + " ::: Value->" + value);
};
}
From other answers I did infer a few things:
Understand Prototypical Inheritance in JS ?!
ng-repeat creates child scope that affects these radios inside ng-repeat
use $parent on ng-modal in the radio
I did played around, but couldn't make this work, I guess I am making some obvious mistake here.
Here is the fiddle:
http://jsfiddle.net/mw2us37h/
NOTE:
I am not using ng-value but passing a hardcoded value.
Changing to ng-click doesnt work either
Flagged this as a duplicate, but it seems like the solution is to use ng-click instead of ng-change when working with radio buttons in angularjs.
Here is an edit of your fiddle that works: http://jsfiddle.net/mw2us37h/1/
I'm not sure I understand what your trying. I think you like to display the radio button value in the result column and/or have a function on click where the value is passed.
Display the radio button value in result column
I would change the ngModel value so it binds to something city specific. So change:
<input type="radio" name="{{city.name}}-{{$index}}" ng-model="big" value="big_value">
to:
<input type="radio" name="{{city.name}}-{{$index}}" ng-model="city.size" value="big_value">
and
<input type="radio" name="{{city.name}}-{{$index}}" ng-model="small" value="small_value">
to
<input type="radio" name="{{city.name}}-{{$index}}" ng-model="city.size" value="small_value">
So the model points to the same variable city.size, this is where the selected value will be saved. Then change *** in the result column to city.size
See changes fiddle: http://jsfiddle.net/u2kxuyr7/
Get value on ngClick
Use ngChange as you allready do I would do it a bit different for simplicity. Change:
ng-change="check(city.name, whatEverValue)"
to:
ng-change="check(city)"
and the check function would look like:
$scope.check = function(city) {
console.log("City->" + city.name + " ::: Value->" + city.size);
};
See fiddle: http://jsfiddle.net/Lmszxj8s/
Then ngChange is fired on each change.
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
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">
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...
}
};