Bind a list of checkboxes in AngularJS - angularjs

I have a list of checkboxes as following :
<div ng-repeat="formationType in formationTypeList">
<label>
<input type="checkbox" class="md-warn md-align-top-left"
ng-model="formationSelection[$index]"
ng-true-value="{{formationType}}"
name="formationSelection[]">
{{ formationType.nom }}
</label>
</div>
As you can see this checkboxes are initialized with values in formationSelection[] array.
And when I check some checkbox the value of this checkbox is added to that array.
The formationTypeList contains a list of objects, each object is attached to a checkbox.
In my scenario the first time I have the formationSelection[] empty so when I check some checkboxes and I send my form the values in that array will be stored in a database, and when I back o my application I want to see the checkboxes I've selected so I populate that array whith values from the database and then I can see the ones wich was selected.
The problem I have is the checkboxs are only selected in one case if I have in formationSelection[] the first element or the first, second elements or the first, second and third elements, but when I have for example the second and the fourth elemnts, they are not selected.
this is a plunker for the working case :
http://plnkr.co/edit/I7NK8Tkw3Rzwh1Zj2X78?p=preview
and this is a plunker for the non working case :
http://plnkr.co/edit/82FDQlhTtd09scs9cCDz?p=preview
Why I'm getting this behavior, and how can I solve it ?

Keep formationSelection length the same as formationTypeList, it will work.
$scope.formationSelection = (function(selection,list){
var result = new Array(list.length);
Array.prototype.map.call(selection,function(val,index){
var pos = Array.prototype.map.call(list,function(v,i){
return v.codeFormation;
}).indexOf(val.codeFormation);
result[pos] = val;
});
return result;
})($scope.formationSelection,$scope.formationTypeList);
Plunker here.

Related

AngularJS Dependent dropdown with ng-repeat is leaving blank

I am trying to make a dependent dropdown but somehow the second dropdown is always leaving a blank if i am changing the first dropdown.
<select class="form-control DB_Control" id="Sector" ng-model="selected_sector" ng-init="selected_sector = initial_selected_sector" ng-options="each.sector for each in data track by each.sector" ng-change="getSubsector()">
<select class="form-control DB_Control" ng-model='related_subsector3' ng-options="subsector for subsector in sub_sectors track by subsector" >
$scope.getSubsector = function() {
$scope.related_subsector3 = $scope.sub_sectors[0]
}
Just for more information, if i am printing the value of $scope.related_subsector3 in function getSubsector, its printing correct value but its not setting the value in template.
I don't think that would work. What I would try is to create another function called "$scope.getSubSectorChildren()" which would populate the second dropdown on the change of the first one. That way you can keep the data population more flexible and it would be easier to test/debug.

Angular 2: Array with checkbox not working properly

I'm binding one array with Checkbox. However, When I try to change bool attribute for single element of array but it changes for all elements.
My HTML Component is as below.
<div class="col-sm-4" *ngFor="let karyalay of karyalayListFinal">
<div class="checkbox-fade fade-in-primary">
<label>
<input formControlName="karyalay_group" type="checkbox" name="karyalaysCheckbox" value="{{karyalay.karyalayId}}" [(ngModel)]="karyalay.isChecked"
(click)="callEvents(karyalay.karyalayId)">
<span>{{karyalay.karyalayName}}</span>
</label>
</div>
</div>
Now I'm trying to change value of single or selected element as below.
for (let karyalay of this.karyalayListFinal) {
let tempInd = _.findIndex(this.roleMasterEventList, {'KARYALAY_ID': karyalay.karyalayId});
if (tempInd > -1) {
this.karyalayListFinal[tempInd].isChecked = true;
}
}
Actually, if tempInd > -1 then and then only that element's value should be changed. But it changes for all.
Don't know whether this is ngModel issue or what?
Thanks
Putting input tag inside *ngFor will create multiple input tags. And name property for input must be different for all. As HTML configure changes for input property using the name property. So, make this name property unique for every input by keeping a name field in the model passed in *ngFor.
And target the checked property instead of ngModel. And do something like
[checked]="yourmodel.isChecked", keep default value of isChecked property in your model as false.
Hope, it helps.
Sorry, but it seems that your approach is too complicated.
I don't know when you call this for each-loop, but I suppose that you already know or have the id you are searching for at this point. Let's call it searchID.
If you want to find the object with the matching id simply use the for each loop as follows:
this.karyalayListFinal.forEach( el => {
if(el.karyalayId === searchID) {
el.isChecked = true;
}
});
That should solve your problem.
you are running this loop for all the elements in "this.karyalayListFinal"
for (let karyalay of this.karyalayListFinal) {
let tempInd = _.findIndex(this.roleMasterEventList, {'KARYALAY_ID': karyalay.karyalayId});
if (tempInd > -1) {
this.karyalayListFinal[tempInd].isChecked = true;
}
}
might be possible that the condition "tempInd > -1" is satisfied for all the elements in "this.karyalayListFinal" and hence all are changing.
I used [checked]="karyalay.isChecked" instead of ngModel in the HTML Code and it started working.
"name" attribute written in input field must be unique for every element created by the loop
you must bind the id of every object coming in an array "karyalayListFinal" to make them unique.

Default Value for Select with ng-options

jsFiddle: http://jsfiddle.net/shandylion/2r3z1uma/
I need to display a list of objects as a list of dropdowns, where changing a dropdown changes the corresponding element in the list. Ideally, each dropdown should default to that element.
So, with the following data:
$scope.allPeople = [{"name":"Ann", "Age":10},
{"name":"Barb", "Age":20},
{"name":"Carl", "Age":30}];
$scope.selectedPeople = [{"name":"Ann", "Age":10},
{"name":"Carl", "Age":30}];
and the following HTML:
<div ng-repeat="selectedPerson in selectedPeople">
<select ng-options="person as person.name for person in allPeople"
ng-model="selectedPeople[$index]"
name="select-{{$index}}" id="select-{{$index}}"></select>
</div>
there should be two dropdowns, with the first defaulting to "Ann" and the second to "Carl".
I've tried using ng-selected, but that only seems to work with <option> tags, not inside a <select>. Other Stack Overflow posts suggest we should always use ng-options and never an <option> with an ng-repeat, so I'm stuck as to how to get this to default to the appropriate value.
Here's a sample plunker, which has a working solution as well as the faulty one described below.
The pitfall with dropdowns is that when you want to preselect a value from a list of options, the selected model should be a reference pointing to the same object from the bound list. Say you have:
var list = [{ id: 1, value: 'first'}];
var model = { id: 1, value: 'first' };
<select ng-options="item.value for item in list" ng-model="model"></select>
This will not preselect the dropdown, because list[0] and model are not the same object, although they look alike. If you set ng-model to list[0] it should be preselected just fine.
Since you're using person.name for person in allPeople, the selected option returns person.name as value. You're presetting your $scope.selectedPeople array's values as objects, which does not match with what your select list will return, and hence your initial values are not set properly.
If you want to have person.name as the value of each option, you should change your $scope.selectedPeople to this:
$scope.selectedPeople = ["Ann", "Carl"];
On the other hand if you want to return person as the value of each option, change your ng-options expression to person as person.name for person in allPeople, which means you return person and show it as person.name for each person in $scope.allPeople.

AngularJS dropdown selected values need as JSON

I have multiple dropdowns in my application which are populating through a json (which is a map basically) given in controller.
For first dropdown if I select xyz value, then corresponding xyz1 values should come in dropdown and similarly for third dropdown. This all is happening fine currently. But now I want these user selected values to get in json form so that I can send back to backend for further processing. I am not getting selected values but the wrong second dropdown values if I print on console.
codepen and
working plunker
I understand that you need to get values from the dynamic input elements. For that, you need to set ng-model to the input elements, not to the div.
The below updated part would help.
<div ng-init="pageObjectName.pageObjParam={}" ng-repeat="(key , value) in pageObjectName.pageObjMethod">
<input ng-model='pageObjectName.pageObjParam[key]' value='' placeholder="{{key}} - {{value}}"></input>
</div>
Now you can get those values from $scope.pageObjectName.pageObjParam.
Updated Plunker
EDIT
I hope the above part helped to get value from dynamic input fields. Now I suggest you to update the code block like below to get the selected values from dropdown (ie, use one hidden input field for each select) and you will get what you want.
<select id="pageObj" ng-model="pageObjectName.pageObj" ng-options="key for (key,value) in pageData" ng-change="pageObjectName.pageObjParam.pageObj=pageObjectName.pageObj">
<option value=''>Select Page Object</option>
</select>
<input ng-model='pageObjectName.pageObjParam.pageObj' hidden/>
You can have a look at the same plunker now
Your codepen seems to be confusing and not working. As you already have the implemention for dropdown I will continue from here about how to get the data from the drop down and convert the data into a JSON.
After getting the data from the dropdown create a JSON object and store it.
I have written a small example to show how to store the data.
$scope.selectedState = function(item) {
var output = {};
output.name = item.name;
$scope.viewOutput = output;
};
Update:
I tried hard but could not get the values using angular way. If you are still looking for an answer then we can use basic javascript way. Refer plunker for the same.
$scope.submitMyForm = function() {
/* while compiling form , angular created this object*/
var pgObj = $scope.pageObj;
var pgClass = $scope.pageClass;
var pgMethod = $scope.pageObjMethod;
var pgObjvalue = document.getElementById('pageObj').value;
var pgClassvalue = document.getElementById('pageClass').value;
var pgMethodvalue = document.getElementById('pageMethod').value;
$scope.output = {'object' : pgObjvalue, 'class': pgClassvalue, 'method': pgMethodvalue};
console.log(data);
};
Working Plunker.
P.S: If you figured out the answer using angular way then do let me know after posting it in the answer section.

dependent ng-models inputbox and select Angular js

I am having one text box and one dropdown.
I want filtering in ng-repeat section based on both of the above control.
Means if i select name in dropdown and in text box as I typing the filtering should work based on name
and if in dropdown if i select EployeeID then filtering should be work based on Employee.
<input id="txtSearchText" ng-model="searchText"/>
<select>
<option>name</option>
<option>EmployeeID</option>
</select>
<div ng-repeat="u in users">
name : {{u.name}} || EID: {{u.eid}} :
<!-- here i want result -->
</div>
The link that domakas directed you to above should help, but the example is slightly different since it filters using 3 different text input boxes.
You are missing a few things here. The first thing is you need to apply a filter to in the ng-repeat for the users div.
<div ng-repeat="u in users | searchText">
The problem that you run into here, which I am sure you are aware of is that it will filter on all of the values in the users array. You seem to want to only filter on the value in the users array that the dropdown has specified. This means we will have to tie the filter to the dropdown in some fashion to make it dynamic.
The way I would do this is to make the filter an object and not just pure text.
$scope.searchText = {name: '', eid: ''};
Now you need to have the model of your input box tied to this object, but where it stores the value needs to be dynamic based on what the value of the dropdown
<input id="txtSearchText" ng-model="searchText[filter]" />
<select ng-model="filter">
<option value="name" selected>name</option>
<option value="eid">EmployeeID</option>
</select>
The above code will store the value of the dropdown in the correct value of the searchText object. This means that the filter will now use this object to filter out the results in the users div instead of just a string, which it would compare to the full JSON object.
Edit:
Added a watch on the 'searchText' object to clear the other value if the dropdown is switched. Without this the old filter value was still in the 'searchText' object, which caused it to filter on both values.
$scope.$watch('filter', function() {
if($scope.filter == "eid") {
$scope.searchText.name = '';
} else {
$scope.searchText.eid = '';
}
});
Here is a JSFiddle with a working example:
http://jsfiddle.net/glandrum101/NM5A5/1/

Resources