Angular ngOptions track by object keys - angularjs

I would like to create a select element with ngOptions – so far so good:
<select ng-options="currency for (code, currency) in currencies track by code"
ng-model="something.currency"></select>
Now I want to track the options by the object key (so the value of the ng-model should be the key and not the value of the object). Is this possible in some simple way and how?

Is it what you're looking for ?
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.currencies_old = [
{code: "USD", curr: "$"},
{code: "IND", curr: "INR"}
];
$scope.currencies = {"USD": "USDollars", "EUR": "Euro"};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="GreetingController">
<select ng-model="item" ng-options="key as value for (key , value) in currencies"></select>
Code: {{item}}
<br/> <br/>
<select ng-options="item as item.curr for item in currencies_old track by item.code" ng-model="item_old"></select>
Code: {{item_old.code}}
</div>

Related

how to use indexof in array set in angularjs

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myctrl', function($scope) {
$scope.state = [{name:'TamilNadu', code:1}, {name:'Kerala', code:2}, {name:'Karnataka', code:3}];
$scope.onChange = function() {
var a = this.drop.state; }
});
</script>
<body>
<div ng-app="myApp" ng-controller="myctrl">
State :
<select id="stat" ng-model="drop.state" ng-change="onChange()">
<option ng-repeat = "x in state"> {{x.name}} </option>
<select>
</div>
</body>
In this code, I can be able to get the selected value from the textbox in the variable a. Now, I need to get the code value of the name selected. Is it possible using indexof(). And I need it in dynamic ie., when the 'state' is selected I need that corresponding 'code' from the array set.
<option value="{{x}}" ng-repeat = "x in state"> {{x.name}} </option>
If you add the value on your Option, you may get the complete object, and accessing the code and the Value
you can assign code as value to option
<option ng-repeat = "x in state" ng-value="x.code"> {{x.name}}
Demo
var app = angular.module('myApp', []);
app.controller('myctrl', function($scope) {
$scope.drop = {}
$scope.state = [{name:'TamilNadu', code:1}, {name:'Kerala', code:2}, {name:'Karnataka', code:3}];
$scope.onChange = function() {
var a = $scope.drop.state
console.log(a)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myctrl">
State :
<select id="stat" ng-model="drop.state" ng-change="onChange()">
<option ng-repeat = "x in state" ng-value="x.code"> {{x.name}} </option>
</select>
</div>
Even though the other answer is valid, this is the right way to go about it:
<select id="stat" ng-model="drop.state" ng-options="x.code as x.name for x in state" ng-change="onChange()">
<option value="">Select a value</option>
</select>
If the purpose of the ng-change was to get the state code, this way it's not needed. Your ng-model will be equal to the selected state code.
You can bind data to a single property., and can access both. with preferred ng-options .
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myctrl', function($scope) {
$scope.state = [{
name: 'TamilNadu',
code: 1
}, {
name: 'Kerala',
code: 2
}, {
name: 'Karnataka',
code: 3
}];
$scope.onChange = function() {
alert(this.drop.state.name);
alert(this.drop.state.code);
}
});
</script>
<body>
<div ng-app="myApp" ng-controller="myctrl">
State :
<select id="stat" ng-model="drop.state" ng-options= "x as x.name for x in state" ng-change="onChange()"> </select>
</div>
</body>

AngulaJS ng-options initially selected value from an

I have an object with property: value structure with should be used for the ng-options to create the select dropdown. I also have a ng-model variable which contains the property which should be currently selected. The problem is that I can't figure out how to fix the initial selection.
You can find the code here
<select ng-model="selectedCar" ng-options="id as value for (id, value) in cars track by id">
http://jsbin.com/wukanenozu/1/edit?html,js,output
Do not use "track by"
Do not use as and track by in the same expression. They are not
designed to work together.
<select ng-model="selectedCar" ng-options="id as value for (id, value) in cars ">
</select>
DEMO
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.cars = {
frd : "Ford",
ft1 : "Fiat",
vlv : "Volvo"
}
$scope.selectedCar = 'ft1';
});
<!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">
<p>Select a car:</p>
<select ng-model="selectedCar" ng-options="id as value for (id, value) in cars ">
</select>
<h1>You selected model: {{selectedCar}}</h1>
</div>
<p>This example demonstrates the use of an object as the data source when creating a dropdown list.</p>
</body>
</html>

Default value given in ng-model is not selected in drop down

I was trying simple select drop down in my app. Where I have set a default value in ng-model. But on load the drop down does not select the ng-model value.
Below are my codes:
HTML:
View <select ng-model="viewby" ng-change="setItemsPerPage(viewby)"><option>3</option><option>5</option><option>10</option><option>20</option><option>30</option><option>40</option><option>50</option></select> records at a time.
Js:
$scope.viewby=3
$scope.setItemsPerPage = function(num) {
console.log( num);
}
Here ng-change is working perfectly.
Here '3' should be selected on load. I tried ng-init and selected='selected' also and both are not working. Any suggestion will help.--thanks
Try like below snippet. Here default selected option was 20, you can change it to your need.
var app = angular.module('app', []);
app.controller("ctrl", function($scope) {
$scope.selectedOption = 20;
$scope.setItemsPerPage = function(num) {
console.log(num);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ctrl">
View
<select ng-model="selectedOption" ng-change="setItemsPerPage(selectedOption)">
<option>3</option>
<option>5</option>
<option>10</option>
<option>20</option>
<option>30</option>
<option>40</option>
<option>50</option>
</select>
records at a time.
</div>
</div>
In angular, Better way is to define the options as array and bind them, so that ng-model will get updated.
JS:
$scope.model = 30;
$scope.options = [10, 20, 30,40,50];
HTML
<select ng-change="setItemsPerPage(model)" ng-model="model" ng-options="value for value in options"></select>
DEMO

angular material md-select using track by but still getting $$hashKey

I'm trying to get rid of the $$hashKey value that angular adds to your model value. According to most sources implementing a track by should solve this issue but I'm doing something wrong.
The vm.productTypes is any array of objects with id properties that are GUIDs.
Resulting model value...
$$hashKey: "object:445"
id: "9e695340-d10a-40ca-9cff-e9a93388912a"
name: "Medical"
type: 1
typeString: "ProductTypes"
HTML Code :
<md-select id="type" ng-model="vm.currentProduct.productType" name="type"
ng-model-options="{trackBy: '$value.id'}"
required>
<md-option ng-repeat="pt in vm.productTypes track by pt.id" ng-value="pt">
{{pt.name}}
</md-option>
</md-select>
Where am I going wrong?
Update:
Seems that the name attribute is causing this strange behavior. Bug?
http://codepen.io/anon/pen/LNpMYJ
Use ng-model-options="{ trackBy: '$value.id' }".
If you are getting list data through $http call, First prepare model object and then load list data.
Or prepare model object and put into an object which is holding hole form data
Link.
<html>
<head>
<title>$$HaskKey Remover</title>
<script src="https://code.angularjs.org/1.3.8/angular.min.js></script>
<script>
var myApp= angular.module('MyApp', []);
myApp.controller('MainCtrl', ['$scope',
function($scope) {
$scope.list = [
{key: "1", name: "Rose"},
{key: {id:2}, name: "Sachin"},
{key: {id:3}, name: "Sandy"}
];
console.log($scope.list);
}
]);
</script>
<head>
<title>Removing $$hashKey when using ng-options</title>
</head>
<body ng-app='MyApp'>
<div ng-controller='MainCtrl'>
<form>
<label for="Select Box">Make a choice of Players:</label>
<select name="selectBx" id="selectBx" ng-model="optionsData"
ng-options="item.name for item in list track by item.key">
</select>
</form>
</div>
</body>
</html>

ng-select gives only string, but I want an integer

This is my angular html file code. In my mongo database frequencyType added as frequencyType = "1", but I want frequencyType = NumberInt(1);
<div class="span4">
<select class="span12 combobox" ng-model="frequencyType" required>
<option value="1">Daily</option>
<option value="2">Weekly</option>
<option value="3">Monthly</option>
<option value="4">Yearly</option>
</select>
</div>
I get in my database frequencyType = "1" but I want frequencyType = NumberInt(1).
There is an easier way:
Just use value*1 as your id, that will convert the string to int without changing the value... assuming the id is an integer.
so the result is>
<div ng-app ng-controller="MyCtrl">
<select ng-model="selectedItem" ng-options="selectedItem*1 as selectedItem for selectedItem in values"></select>
selectedItem: {{selectedItem}}
</div>
This will work in more cases, since indexOf is not available in objects, only in arrays. This solution works for objects with integers as keys (for example if some keys are missing, or if you use db ids)
Most solutions discussed here require using the ngOptions directive instead of using static <option> elements in the HTML code, as was the case in the OP's code.
Angular 1.6.x
Edit If you use Angular 1.6.x, just use the ng-value directive and it will work as expected.
angular.module('nonStringSelect', [])
.run(function($rootScope) {
$rootScope.model = { id: 2 };
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<div ng-app="nonStringSelect">
<select ng-model="model.id">
<option ng-value="0">Zero</option>
<option ng-value="1">One</option>
<option ng-value="2">Two</option>
</select>
{{ model }}
</div>
Older versions
There is a way to make it work while still using static elements. It's shown in the AngularJS select directive documentation.
The idea is to use a directive to register a parser and a formatter on the model. The parser will do the string-to-int conversion when the item is selected, while the formatter will do the int-to-string conversion when the model changes.
Code below (taken directly from the AngularJS documentation page, credit not mine).
https://code.angularjs.org/1.4.6/docs/api/ng/directive/select#binding-select-to-a-non-string-value-via-ngmodel-parsing-formatting
angular.module('nonStringSelect', [])
.run(function($rootScope) {
$rootScope.model = { id: 2 };
})
.directive('convertToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(val) {
return parseInt(val, 10);
});
ngModel.$formatters.push(function(val) {
return '' + val;
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="nonStringSelect">
<select ng-model="model.id" convert-to-number>
<option value="0">Zero</option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
{{ model }}
</div>
I've just had the same problem and figured out the right way to do this - no 'magic' required. :)
function MyCtrl($scope) {
$scope.values = [
{name : "Daily", id : 1},
{name : "Weekly", id : 2},
{name : "Monthly", id : 3},
{name : "Yearly", id : 4}];
$scope.selectedItem = $scope.values[0].id;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
<select ng-model="selectedItem" ng-options="selectedItem.id as selectedItem.name for selectedItem in values"></select>
selectedItem: {{selectedItem}}
</div>
I think the angular way to do this is to use the directive "convert-to-number" in the select tag.
<select class="span12 combobox" ng-model="frequencyType" required convert-to-number>
<option value="1">Daily</option>
<option value="2">Weekly</option>
<option value="3">Monthly</option>
<option value="4">Yearly</option>
</select>
You can see the documentation and a fiddle here at the end of the page : https://docs.angularjs.org/api/ng/directive/select
I suggest you to try to use indexOf.
JS
function MyCtrl($scope) {
$scope.values = ["Daily","Weekly","Monthly","Yearly"];
$scope.selectedItem = 0;
}
HTML
<div ng-app ng-controller="MyCtrl">
<select ng-model="selectedItem" ng-options="values.indexOf(selectedItem) as selectedItem for selectedItem in values"></select>
selectedItem: {{selectedItem}}
</div>
Demo Fiddle
So send to mongoDB $scope.selectedItem value
This is the easiest way I have found so far:
function Controller($scope) {
$scope.options = {
"First option" : 1,
"Second option" : 2,
"Last option" : 10
}
$scope.myoption = 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="Controller">
<select ng-model="myoption" ng-options="label for (label, value) in options"></select>
Option Selected: {{myoption}}
</div>
Or, if you want to use numeric indexes:
function Controller($scope) {
$scope.options = {
1 : "First option",
2 : "Second option",
10 : "Last option"
}
$scope.myoption = 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="Controller">
<select ng-model="myoption" ng-options="value*1 as label for (value, label) in options"></select>
Option Selected: {{myoption}}
</div>
For Angular 2, follow the rabit...

Resources