angularjs - setting select element option value with JS object - javascript

I am new to AngularJS so please bear with me.
Following is the the JSON string I am trying to bind in the select element:
[
{"Name":"Value 1","ID":1},
{"Name":"Value 2","ID":2},
{"Name":"Value 3","ID":3},
{"Name":"Value 4","ID":4}
]
Following is the JS object for the same:
function NameValue(nameValue){
var self = this;
self.ID = nameValue.ID;
self.Name= nameValue.Name;
}
I am parsing the above JSON string, looping through the objects and pushing items into an array using the above JS object like:
angular.forEach(angular.fromJson(jsonString), function (value, key) {
$scope.Values.push(new NameValue(value));
});
Following is my select with agularjs bindings:
<select ng-model="SelectedName" ng-options="x.Name for x in Values">/select>
When I select a value in the select element, the entire NameValue object is getting set into the SelectedName property which is what I am trying to do.
Now when I try to set the SelectedName property dynamically, the value is not getting selected and an empty option element is getting added in the select element. I used the {{SelectedName}} to check the value when set dynamically and when I select the same value in the select element manually and both are {"ID":2,"Name":"DAO"} which are exactly same. What am I doing wrong here?

The syntax of ng-options is something like this.link
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
Suppose you have controller like this
app.controller('MainCtrl', function($scope) {
$scope.Values = [
{"Name":"Value 1","ID":1},
{"Name":"Value 2","ID":2},
{"Name":"Value 3","ID":3},
{"Name":"Value 4","ID":4}
];
$scope.SelectedByName='Value 2'; //Default setting drop down by Name property
$scope.SelectedById=4; //Default setting drop down by ID property
});
If you follow the below syntax then either name or Id property will be set to selected variable.
If you need default selection of drop down then you need to set the respective model in controller.(as above)
HTML :
<body ng-controller="MainCtrl">
By name :
<select ng-options="value.Name as value.Name for value in Values"
ng-model="SelectedByName" ng-change="Print()"></select>
Selected value is : {{SelectedByName}}
<br>
By ID :
<select ng-options="value.ID as value.Name for value in Values"
ng-model="SelectedById" ng-change="Print()"></select>
Selected id is : {{SelectedById}}
</body>
Demo plunker Click here

First of all - you should initialize SelectName in your $scope.
Next you can use:
ng-options="x.id as x.name for x in values"
Can you display {{values}} in your template and it's look good? Maybe you have a problem with redraw template when data is push into value. Check this way also.

here is a working snippet. i guess you didn't defined Values as an array, before pushing anything you have to define the variable as an array.
var app = angular.module('myApp', []);
function NameValue(nameValue) {
var self = this;
self.ID = nameValue.ID;
self.Name = nameValue.Name;
}
app.controller('myCtrl', function($scope) {
$scope.Values = [];
$scope.jsonString = [{
"Name": "Value 1",
"ID": 1
}, {
"Name": "Value 2",
"ID": 2
}, {
"Name": "Value 3",
"ID": 3
}, {
"Name": "Value 4",
"ID": 4
}];
angular.forEach(angular.fromJson( $scope.jsonString), function (value, key) {
$scope.Values.push(new NameValue(value));
});
console.log($scope.Values);
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model="SelectedName" ng-options="x.Name for x in Values">/select>
</div>
</body>
</html>

I had the same issue and i found a solution:
Don't use ng-options but <option> tag
<select ng-model="..."> <option ng-repeat="..."> {{ ... }} </option></select>

Related

how to pass select option value in angularjs

I have a below code snippet
HTML
<div ng-controller="MyCtrl">
<div ng-if="quan!=true">
<select ng-model="selectedItems" ng-init="selectedItems = selectedItems + ''">
<option ng-repeat="value in arr | limitTo:quantity">{{value}}</option>
</select>
</div>
<div>
Submit
</div>
</div>
JS
$scope.arr = [];
$scope.quan=false;
for(var a=1; a<=10; a++) {
$scope.arr.push(a);
}
$scope.selectedItems = $scope.arr[0];
$scope.quantity = 10; //just hardcoded
Here, when I click submit button, I didn't get the value whatever I have selected in the dropdown. I was getting undefined for selectedItems.
And also first option needs to be selected in the select box.
I think I'm missing something!
After changing to $scope.selectedItems = $scope.arr[0];, you need to initialize your option value ng-init="selectedItems = selectedItems + ''" because angular use strict comparison.
See this working fiddle.
also you don't need to pass selected item in click event, submit(selectedItems). because it is already in controller scope.
Also I would recommend changing your options structure to avoid ng-init.
Something like :
options = [{
name: 'key1',
value: 'value1'
}, {
name: 'key2',
value: 'value2'
}];
HTML:
<select ng-model="selectedItem" >
<option ng-repeat="value in arr | limitTo:quantity">{{value}}</option>
</select>
<div>
Submit
</div>
JS:
$scope.arr = [];
for(var a=1; a<=10; a++) {
$scope.arr.push(a);
}
$scope.selectedItem = $scope.arr[0];
$scope.quantity = 10; //just hardcoded
$scope.submit = function(){
console.log($scope.selectedItem); // you will get the selected value here, if you want it after button click.
};
Because of angular's 2 way binding, it would be available as soon as you select something. You do not have to pass it as function parameter from HTML

Angular 1.5 "track by" ruines binding in ng-options

I need to select option in combobox from ajax loaded data. That data comes as list of objects. The problem is that ng-option compares objects by reference and thus setting model to objects element results in appearing new empty option in combobox instead of selecting correct option.
The known workaround is to use track by expression.
And here is example code:
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.roles =[
{ key:"administrator", value:"ROLE_ADMIN" },
{ key:"operator", value:"ROLE_OPERATOR" },
];
// this emulates data from server
// won't work without 'track by'
$scope.role={ key:"administrator", value:"ROLE_ADMIN" };
});
Template:
<body ng-app="myApp" ng-controller="myCtrl">
0: <input ng-model="roles[0].key" />
<br>
1: <input ng-model="roles[1].key" />
<br>
select role: <select ng-model="role" ng-options="r.key for r in roles track by r.value">
</select>
<pre>selected role={{role|json}}</pre>
</body>
Here another problem arises. When one selects role in combobox and then
changes it's "key" property in textbox, then selected role stays unchanged. So it looks like binding is suddenly gets broken.
https://jsfiddle.net/xLqackxw/8/
from Angular documentation https://docs.angularjs.org/api/ng/directive/ngOptions
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
So:
<select ng-model="role" ng-options="r as r.key for r in roles track by r.value"></select>
'$scope.role' value will be object like { key:"administrator", value:"ROLE_ADMIN" } or { key:"operator", value:"ROLE_OPERATOR" }

ng-model having a string value and ng-option integer

Here is my JSON array:
array=[ {id:1, name:'A'} , {id:2, name:'B'} ]
And in ng-model I am setting value which may be string like
modelValue='1'
I had ng-option
ng-option="option.id as option.name for option in array"
ng-model="modelValue"
But it is not showing selected value of ng-model in select
And in ng-model I am setting value which may be string like
You should provide the same primitive or object type to your $scope.modelValue as of id. This is the preferred way.
If only the JSON array is being fetched dynamically AND type consistency is not guaranteed then you can apply a function to convert it to the type that is set to $scope.modelValue
In HTML
<select ng-model="modelValue" ng-options="getId(option.id) as option.name for option in myarray">
</select>
In Controller
$scope.modelValue='1';
$scope.myarray=[ {id:1, name:'A'} , {id:2, name:'B'} ];
$scope.getId = function(id)
{
if(typeof $scope.modelValue == "string")
return String(id);
else if(typeof $scope.modelValue == "number")
return parseInt(id);
}
COMPLETE EXAMPLE
Also see this answer
Here is a working JSFiddle example based on your description: http://jsfiddle.net/9pLdgmm1/1/
You should use ng-options instead of ng-option
<select ng-options="p.name for p in people"
ng-model="selectedPerson">
</select>
You should take ng-options instead of ng-option, als you should take integer itself instead of string..
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model="modelValue" ng-options="option.id as option.name for option in names">
</select>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = [ {id:1, name:'A'} , {id:2, name:'B'} ]
$scope.modelValue = 1;
});
</script>
<p>This example shows how to fill a dropdown list using the ng-options directive.</p>
</body>
</html>
Please run the above snippet
Here is a Working DEMO
This should not be selected, because of all id is in numbers. If you want to make it select, then parse your $scope.modelValue to numbers like this.
$scope.modelValue= parseInt("1");
Also change your ng-options instead of ng-option
You have a syntax error in ng-options:
<select ng-options="option.name for option in array" ng-model="modelValue"></select>
var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function($scope) {
$scope.array = [{
id: 1,
name: 'A'
}, {
id: 2,
name: 'B'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<fieldset ng-controller="FirstCtrl">
<select ng-options="option.name for option in array" ng-model="modelValue"></select>
modelValue is: {{modelValue}}
</fieldset>
</div>

Element got removed after applying filter

I am applying filters to get the data of a particular field through a dropdown, but when I select any option the filter applied elements get removed. How can I resolve it?
HTML code:
<body ng-controller="MyCtrl">
<div>
<label>Country filter</label>
<input type="text" ng-model="countryFilter" />
<label>Order by</label>
<select ng-model="selectedOrder">
<option ng-repeat="option in options">{{option}}</option>
</select>
</div>
<ul>
<li ng-repeat="detail in details | filter:{loc : selectedOrder}">{{ detail.country }}</li>
</ul>
</body>
JS code:
var app = angular.module('plunker', []);
app.controller('MyCtrl', function($scope) {
// order by options
$scope.options = ['1', '2', '3'];
// all countries
$scope.details = [{
id:1, country:'Finland', address:'Mainstreet 2',detail:[{
loc:'1'
}]
},{
id:2, country:'Mexico', address:'Some address',detail:[{
loc:'2'
}]
},{
id:3, country:'Canada', address:'Snowroad 45',detail:[{
loc:'3'
}]
}];
});
I want to filter through options and loc value. Where am I going wrong?
You don't need to write a custom filter.
Change your filter to: filter:{detail: {loc:selectedOrder}}
I added <option value=""></option> to the dropdown and set $scope.selectedOrder = ""; in order to show all countries by default.
Codepen
filter:{prop:value} returns objects which have property prop at first level, it does not watch in object deeper. (When usual filter without params does it)
Your objects in array details do not have 'loc' property. So nothing fits filter.
You can not filter by exact property of 2nd and deeper levels of object with standard angular filter. Implement your own or change data.

Select default value at ng-options

I have this code and information:
$scope.options = [
{ id: 1, label: "My label" },
{ id: 2, label: "My label 2" }
];
$scope.selected = 2;
<select ng-options="opt.label for opt in options" ng-model="selected">
<option value="">Select one</option>
</select>
However, the options are created like this:
<select ng-options="opt.label for opt in options" ng-model="selected">
<option value="">Select one</option>
<option value="0">My label</option>
<option value="1">My label 2</option>
</select>
How can I set the selected option to My label 2? I know it can be done:
$scope.selected = $scope.options[1];
But my problem is that option is created in a directive, and at that moment I don't know 1) how many values has $scope.options, nor 2) what is the index of the selected option in database. The only thing I know is the id (which is in the object).
The html of my directive is something like this:
<select ng-switch-when="select" ng-model="form.model[element.model]" ng-options="{{element.rule}}"></select>
Where element.rule is:
rule: "role.role for role in element.options"
And element.options has the array with options, and form.model[element.model] has the id of the option selected.
How can I get the index of the element with ID X in the array $scope.options? I'm very sure that will give me the solution, but I don't know how to do it...
Just set the correct model value when initiating the controller. You can easily get the correct array value if you know the ID by using a filter:
$scope.selected = $filter('filter')($scope.options, {id: 2})[0];
The issue with your code as I see it is that the 'selected' value coming out of your database is the ID of the object selected and not the object itself. This is fine but because of that difference you can't simply set
$scope.selected = 2 //assuming 2 is the value coming from your database
because the value '2' does not exist in your option array. The Object with an ID of 2 does.
If you can always guarantee the options you have in the option array are from 1-n and in that order, you can accomplish this by simply using this instead:
$scope.options = [
{ id: 1, label: "My label" },
{ id: 2, label: "My label 2" }
];
var selectedIdFromDatabase = 2;
$scope.selected = $scope.options[selectedIdFromDatabase-1];
If you can't make that guarantee (and even if you can for now, it may not be a good idea to make that assumption in your code) you'll need iterate over the array of objects you have to identify the object with an ID of the selectedId from your database.
The answer to this question has a great write-up about the type of data-processing you'll need to do and a lot more information about javascript objects in general.

Categories

Resources