Get selected item with ng-options - angularjs

I have an array with attributes and I'm trying to select a certain one on load.
Each of my attributes have attribute object, type object and an array of attributeValues.
I want to select the attribute value with chosen=true
Here's my Angular code:
app.controller('MainCtrl', function($scope) {
$scope.profileData = { "attributes": [{
"attribute": {
"id": 56,
"name": "Hárlitur",
"typeID": 5,
"visibleToUsers": true
},
"type": {
"id": 5,
"typeName": "list"
},
"attributeValues": [{
"id": 109,
"attributeID": 56,
"value": "Ljós",
"chosen": true
}, {
"id": 110,
"attributeID": 56,
"value": "Dökkur",
"chosen": false
}],
"valueText": null
}]};
$scope.changeValue = function changeValue(attribute, value) {
alert(JSON.stringify({"attributeID":attribute.attribute.id, "type": attribute.type.typeName, "value":value.id}));
};
});
Here's my HTML code:
<div ng-repeat="attribute in profileData.attributes">
<select ng-change="changeValue(attribute, attributeValue)" ng-options="item.id as item.value for item in attribute.attributeValues" ng-model="attributeValue.id"></select>
</div>
Here's my plunker:
http://plnkr.co/edit/VMbmSB?p=preview

I don't know if this is the best solution to your problem, but it works.
What I ddid was to simply create a function to search for the chosen value set as true. Upon finding that value I set the scope model as that attribute value. Then I called that function immediately afterwards.
$scope.selectChosen = function selectChosen() {
var attrVals = $scope.profileData.attributes[0].attributeValues;
for (var i = 0; i < attrVals.length; i++) {
if (attrVals[i].chosen) {
$scope.attributeValue = attrVals[i];
break;
}
}
};
$scope.selectChosen();
The complete plunker is at: http://plnkr.co/edit/UcmQ8Q?p=preview

I found a better Angular-ish solution:
<div ng-repeat="attribute in profileData.attributes">
<select ng-model="attributeValue" ng-change="changeValue(attribute, attributeValue)">
<option value="">Select</option>
<option ng-repeat="obj in attribute.attributeValues" value="{{obj.id}}" ng-selected="obj.chosen">{{obj.value}}</option>
</select>
</div>

Related

Using ng-repeat and $index how to set default selected in select

Using ng-repeat and $index how to show default selected value using angularjs
my code :
I have SelectValues :
"Jewelery_And_Diamond_Type": [
{
"id": 33,
"value": "Earrings"
},
{
"id": 35,
"value": "Gemstones"
},
{
"id": 34,
"value": "Loose Diamonds"
},
{
"id": 32,
"value": "Necklaces"
},
{
"id": 31,
"value": "Pendants"
},
{
"id": 30,
"value": "Rings"
} ]
selected Value is "Earings"
In my HTML
<select ng-model="categoryval.Jewelery_And_Diamond_Type[$index]" ng-init="categoryval.Jewelery_And_Diamond_Type[$index] = SelectValues.Jewelery_And_Diamond_Type.indexOf(0)" ng-options="option.value for option in SelectValues.Jewelery_And_Diamond_Type track by option.id">
If I wrote like this means no value as selected by default. I need exact selected Values based on the $index.
Use ng-options
<select ng-model="value" ng-init="value='Earrings'" ng-options="mode.value as mode.value for mode in storageResult.Jewelery_And_Diamond_Type">
</select>
DEMO
In a select, ng-model will determine which option is selected.
So if you strictly want to select an item by its index in the array you need to create the object model like so:
$scope.selected = $scope.values[0];
values being your json array.
The select will then look like:
<select
ng-model="selected"
ng-options="option.value for option in values track by option.id">
</select>
Don't use ng-init in the html, it's bad practice.
function MyController() {
this.values = [
{
"id": 33,
"value": "Earrings"
},
{
"id": 35,
"value": "Gemstones"
},
{
"id": 34,
"value": "Loose Diamonds"
},
{
"id": 32,
"value": "Necklaces"
},
{
"id": 31,
"value": "Pendants"
},
{
"id": 30,
"value": "Rings"
} ];
this.selected = this.values[0];
};
angular.module('app', []);
angular.module('app')
.controller('MyController', MyController);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MyController as ctrl">
<select
ng-model="ctrl.selected"
ng-options="option.value for option in ctrl.values track by option.id">
</select>
<br>
{{ctrl.selected | json}}
</div>
</div>
If you know the id where default selected value is available you can include it in a scope variable and inject the variable in
<option value="">{{selectedType}}</option>
$scope.selectedType= categoryval.Jewelery_And_Diamond_Type[defaultIndex].valu‌​e
value ="" helps you to fill the empty first option
Remove ng-init and set default value in controller so that you can unit test whether default option is always what you want it to be.
In controller:
$scope.defaultValue = $scope.SelectValues.Jewelery_And_Diamond_Type[0];
then change HTML
<select ng-model="defaultValue" ng-options="option.value for option in SelectValues.Jewelery_And_Diamond_Type track by option.id">
Plunker

handling json response Array

I have a json response as given below from backend
JSON:
{
"json": {
"response": {
"servicetype": "1",
"functiontype": "10011",
"statuscode": "0",
"statusmessage": "Success",
"data":{
"roleid": 36,
"rolename": "Product Managers",
"divisionlabel": "Department ",
"subdivisionlabel": "Category",
"roleinformation": {
"QA": [
{
"White Box Testing": 10
}
]
}
},
{
"roleid": 38,
"rolename": "Managers",
"divisionlabel": "Department ",
"subdivisionlabel": "Category",
"roleinformation": {
"QA": [
{
"Black Box Testing": 10
}
]
}
}
}
}
}
}
I have inserted my role names in a dropdown $scope.model.rolename .
If my rolename is selected as product managers I want to give value of my $scope.maxcount value as "White Box Testing": 10 .It should be dynamic , based on selection the value will change. Now in dropdown if I select Manager the $scoope.maxcount for manager value will change. I have done till dropdown , dont know to handle after it .
JS:
` `UserService.getAssignRoles(json).then(function(response) {
if (response.json.response.statuscode == 0 && response.json.response.statusmessage == 'Success')
{
$scope.model.roles= [], assignrolesArray = [];
assignrolesArray = unasresdata.concat(assresdata);
$scope.model.assignroles = assignrolesArray;
}
});
HTML:
<select class="form-control" name="role"
ng-model="model.rolename"
ng-change="getassignRole(model.rolename)">
<option selected>Select Roles</option>
<option ng-repeat="role in model.assignroles track by $index"
value="{{role.rolename}}">{{role.rolename}}</option>
</select>
<input type = "text" ng-model=$scope.maxcount>
You can pass your model.assignroles and scope value into this getassignRole() function and from that, you can get property and set it to your scope variable.
Do install lodash library and inject it.
HTML
ng-change="getassignRole(model.assignroles, model)"
JS
$scope.getassignRole= function(model.assignroles, rolename){
console.log(model.assignroles);
var test = _.filter(model.assignroles, function(o){
return o.rolename === rolename;
})
console.log(rolename);
console.log(test[0].roleinformation);
};
Sample jsfiddle: https://jsfiddle.net/alpeshprajapati/5kpxzrgf/1/
You can access required property then.
Hope it helps.

What would be angular ng-option equivalent of this select?

I am struggling to get this into an ng-option. Is it even possible?
<select ng-model="detail_type_id">
<optgroup ng-repeat="type in data.detailTypes" label="{{type.name}}">
<option ng-repeat="t in type.children" value="{{t.id}}">{{t.name}}</option>
</optgroup>
</select>
DetailTypes looks like this:
[
{"id":7,
"parent_id":null,
"name":"Contact",
"children":[
{"id":8,
"parent_id":7,
"name":"Address",
"children":[]
},
{"id":12,
"parent_id":7,
"name":"Something else",
"children":[]
}
]},
{"id":16,
"parent_id":null,
"name":"Other",
"children":[
{"id":10,
"parent_id":16,
"name":"Remarks",
"children":[]}
]
}
]
Child id needs to be selected. Nesting cannot be deeper.
The ngOptions directive does not work with multidimensional objects. So you need to flatten your array to use it.
I wrote a filter for that:
app.filter('flatten' , function(){
return function(array){
return array.reduce(function(flatten, group){
group.children.forEach(function(child){
child.groupName = group.name;
flatten.push(child)
})
return flatten;
},[]);
}
})
And the HTML part would be like this:
<select ng-model="detail_type_id"
ng-options="item.id as item.name
group by item.groupName for item
in data.detailTypes | flatten track by item.id">
</select>
Plunker (version #1 with filter):
https://plnkr.co/edit/dxi7j8oxInv2VRJ1aL7F
I also modified your object to be like this:
[{
"id": 7,
"parent_id": null,
"name": "Contact",
"children": [{
"id": 8,
"parent_id": 7,
"name": "Address",
"children": []
}, {
"id": 12,
"parent_id": 7,
"name": "Something else",
"children": []
}]
}, {
"id": 16,
"parent_id": null,
"name": "Other",
"children": [{
"id": 10,
"parent_id": 16,
"name": "Remarks",
"children": []
}]
}]
EDIT:
After suggestion I wrote another version without the filter, but flattening the array inside the controller.
Additional Controller JS:
$scope.flattenDetailTypes = flattenDetailTypes($scope.data.detailTypes);
function flattenDetailTypes(array){
return array.reduce(function(flatten, group){
group.children.forEach(function(child){
child.groupName = group.name;
flatten.push(child)
})
return flatten;
},[]);
}
Markup:
<select ng-model="detail_type_id"
ng-options="item.id as item.name group by item.groupName for item in flattenDetailTypes track by item.id"></select>
Plunker (version #2 without filter):
https://plnkr.co/edit/D4APZ6

angular predicate filter not returning element

I'm trying to use a predicate function to filter some items because the object structure might be a little too deep for straight template filtering. I have an array of items that I'm tring to filter based on user selected region and user selected country. When I filter the items in the template with the selected region the correct items are rendered. However, I need to filter deeper i.e., the user selects countries of the selected region. The predicate function appears to be filtering the items correctly i.e., printing to console, but the items are not rendering in the template.
{
"id": 2,
"name": "my test app",
"version": "1.0.0",
"regions": [
{
"id": 11,
"name": "LATIN_AMERICA",
"timeZone": "UTC+8",
"selected": true,
"countries": [
{
"id": 47,
"name": "Brazil",
"timeZone": "UTC+08:00",
"isoCode": "BR",
"selected": false
},
{
"id": 46,
"name": "Argentina",
"timeZone": "UTC+08:00",
"isoCode": "AR",
"selected": true
}
]
}
]
},
{
"id": 2,
"name": "my test app",
"version": "1.0.1",
"regions": [
{
"id": 11,
"name": "LATIN_AMERICA",
"timeZone": "UTC+8",
"selected": true,
"countries": [
{
"id": 47,
"name": "Brazil",
"timeZone": "UTC+08:00",
"isoCode": "BR",
"selected": true
},
{
"id": 46,
"name": "Argentina",
"timeZone": "UTC+08:00",
"isoCode": "AR",
"selected": false
}
]
}
]
}
function filterByRegionCountry(app) {
if(vm.selectedCountry !== undefined) {
angular.forEach(app.regions, function(appRegion, i) {
angular.forEach(appRegion.countries, function(appCountry, j) {
angular.forEach(vm.selectedCountry, function(selectedCountry, k) {
if((appCountry.name == selectedCountry.name) && appCountry.selected) {
console.log(app);
return true;
}
});
});
});
}
}
<select class="form-control" ng-model="vm.selectedRegion" ng-options="region.name for region in vm.filterRegions">
<option value="">--select region--</option>
</select>
<select class="form-control" ng-model="vm.selectedCountry" ng-options="country.name for country in vm.selectedRegion.countries" multiple>
<option value="">-- select country --</option>
</select>
<tr ng-repeat="app in vm.appVersions | filter:vm.filterByRegionCountry">
<td>
<label>{{ app.name }}</label>
</td>
<td>
<label>{{ app.version }}</label>
</td>
</tr>
// EDIT
Using .some (see answer below) or for loops with a break fixes the issue.
if(vm.selectedCountry !== undefined) {
for(var i = 0; i < app.regions.length; i++) {
for(var j = 0; j < app.regions[i].countries.length; j++) {
for(var k = 0; k < vm.selectedCountry.length; k++) {
if((app.regions[i].countries[j].name == vm.selectedCountry[k].name) && app.regions[i].countries[j].selected) {
console.log(app);
return true;
break;
}
}
}
}
}
Filter need either true or false to exevalue.
You are using angular forEach and there no break for forEach
Try javascript .some instead
like this
if (vm.selectedCountry) {
return app.regions.some(function (appRegion) {
return appRegion.countries.some(function (appCountry) {
return vm.selectedCountry.some(function (selectedCountry) {
if ((appCountry.name == selectedCountry.name) && appCountry.selected) {
console.log(app);
return true;
}
});
});
});
}
else
return false;

How to set a selected option of a dropdown list control using angular JS

I am using Angular JS and I need to set a selected option of a dropdown list control using angular JS. Forgive me if this is ridiculous but I am new with Angular JS
Here is the dropdown list control of my html
<select ng-required="item.id==8 && item.quantity > 0" name="posterVariants"
ng-show="item.id==8" ng-model="item.selectedVariant"
ng-change="calculateServicesSubTotal(item)"
ng-options="v.name for v in variants | filter:{type:2}">
</select>
After it gets populated I get
<select ng-options="v.name for v in variants | filter:{type:2}" ng-change="calculateServicesSubTotal(item)"
ng-model="item.selectedVariant" ng-show="item.id==8" name="posterVariants"
ng-required="item.id==8 && item.quantity > 0" class="ng-pristine ng-valid ng-valid-required">
<option value="?" selected="selected"></option>
<option value="0">set of 6 traits</option>
<option value="1">5 complete sets</option>
</select>
How can I set the control for value="0" to be selected?
I hope I understand your question, but the ng-model directive creates a two-way binding between the selected item in the control and the value of item.selectedVariant. This means that changing item.selectedVariant in JavaScript, or changing the value in the control, updates the other. If item.selectedVariant has a value of 0, that item should get selected.
If variants is an array of objects, item.selectedVariant must be set to one of those objects. I do not know which information you have in your scope, but here's an example:
JS:
$scope.options = [{ name: "a", id: 1 }, { name: "b", id: 2 }];
$scope.selectedOption = $scope.options[1];
HTML:
<select data-ng-options="o.name for o in options" data-ng-model="selectedOption"></select>
This would leave the "b" item to be selected.
I don't know if this will help anyone or not but as I was facing the same issue I thought of sharing how I got the solution.
You can use track by attribute in your ng-options.
Assume that you have:
variants:[{'id':0, name:'set of 6 traits'}, {'id':1, name:'5 complete sets'}]
You can mention your ng-options as:
ng-options="v.name for v in variants track by v.id"
Hope this helps someone in future.
If you assign value 0 to item.selectedVariant it should be selected automatically.
Check out sample on http://docs.angularjs.org/api/ng.directive:select which selects red color by default by simply assigning $scope.color='red'.
i see here already wrote good answers, but sometime to write the same in other form can be helpful
<div ng-app ng-controller="MyCtrl">
<select ng-model="referral.organization" ng-options="c for c in organizations"></select>
</div>
<script type='text/javascript'>
function MyCtrl($scope) {
$scope.organizations = ['a', 'b', 'c', 'd', 'e'];
$scope.referral = {
organization: $scope.organizations[2]
};
}
</script>
Simple way
If you have a Users as response or a Array/JSON you defined, First You need to set the selected value in controller, then you put the same model name in html. This example i wrote to explain in easiest way.
Simple example
Inside Controller:
$scope.Users = ["Suresh","Mahesh","Ramesh"];
$scope.selectedUser = $scope.Users[0];
Your HTML
<select data-ng-options="usr for usr in Users" data-ng-model="selectedUser">
</select>
complex example
Inside Controller:
$scope.JSON = {
"ResponseObject":
[{
"Name": "Suresh",
"userID": 1
},
{
"Name": "Mahesh",
"userID": 2
}]
};
$scope.selectedUser = $scope.JSON.ResponseObject[0];
Your HTML
<select data-ng-options="usr.Name for usr in JSON.ResponseObject" data-ng-model="selectedUser"></select>
<h3>You selected: {{selectedUser.Name}}</h3>
It can be usefull. Bindings dose not always work.
<select id="product" class="form-control" name="product" required
ng-model="issue.productId"
ng-change="getProductVersions()"
ng-options="p.id as p.shortName for p in products">
</select>
For example. You fill options list source model from rest-service. Selected value was known befor filling list and was set. After executing rest-request with $http list option be done. But selected option is not set. By unknown reasons AngularJS in shadow $digest executing not bind selected as it shuold be. I gotta use JQuery to set selected. It`s important! Angular in shadow add prefix to value of attr "value" for generated by ng-repeat optinos. For int it is "number:".
$scope.issue.productId = productId;
function activate() {
$http.get('/product/list')
.then(function (response) {
$scope.products = response.data;
if (productId) {
console.log("" + $("#product option").length);//for clarity
$timeout(function () {
console.log("" + $("#product option").length);//for clarity
$('#product').val('number:'+productId);
//$scope.issue.productId = productId;//not work at all
}, 200);
}
});
}
Try the following:
JS file
this.options = {
languages: [{language: 'English', lg:'en'}, {language:'German', lg:'de'}]
};
console.log(signinDetails.language);
HTML file
<div class="form-group col-sm-6">
<label>Preferred language</label>
<select class="form-control" name="right" ng-model="signinDetails.language" ng-init="signinDetails.language = options.languages[0]" ng-options="l as l.language for l in options.languages"><option></option>
</select>
</div>
This is the code what I used for the set selected value
countryList: any = [{ "value": "AF", "group": "A", "text": "Afghanistan"}, { "value": "AL", "group": "A", "text": "Albania"}, { "value": "DZ", "group": "A", "text": "Algeria"}, { "value": "AD", "group": "A", "text": "Andorra"}, { "value": "AO", "group": "A", "text": "Angola"}, { "value": "AR", "group": "A", "text": "Argentina"}, { "value": "AM", "group": "A", "text": "Armenia"}, { "value": "AW", "group": "A", "text": "Aruba"}, { "value": "AU", "group": "A", "text": "Australia"}, { "value": "AT", "group": "A", "text": "Austria"}, { "value": "AZ", "group": "A", "text": "Azerbaijan"}];
for (var j = 0; j < countryList.length; j++) {
//debugger
if (countryList[j].text == "Australia") {
console.log(countryList[j].text);
countryList[j].isSelected = 'selected';
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<label>Country</label>
<select class="custom-select col-12" id="Country" name="Country" >
<option value="0" selected>Choose...</option>
<option *ngFor="let country of countryList" value="{{country.text}}" selected="{{country.isSelected}}" > {{country.text}}</option>
</select>
try this on an angular framework
JS:
$scope.options = [
{
name: "a",
id: 1
},
{
name: "b",
id: 2
}
];
$scope.selectedOption = $scope.options[1];

Resources