why isn't my angular options track by id working - javascript

I'm sure I must be doing this wrong, but:
I have an object that stores the id of an item. I also have an array of these items. I need to have a 'select' that represents the currently selected item, but that can also change the selected item.
I have set the 'select's model to the object.selectId.
The 'select' ng-options is "option.Text for option in options track by optionId"
Yet the model and 'select' options types don't match
How do I achieve what I need?
Here's a fiddle of what I am doing: https://jsfiddle.net/vb2xe1mc/5/
Code:
<script>
angular.module('myApp', [])
.controller('myctrl', ['$scope', function($scope) {
$scope.item = {
id: 1
};
$scope.options = [
{Text: "zero", Id: 0},
{Text: "one", Id: 1},
{Text: "two", Id: 2},
{Text: "three", Id: 3}
];
$scope.selectChange = function() {
alert($scope.item.id);
};
}]);
</script>
<div ng-app="myApp">
<div ng-controller="myctrl">
<select ng-model="item.id" ng-options="option.Text for option in options track by option.Id" ng-change='selectChange()'>
</select>
</div>
</div>
If you can, please let me know where I have gone wrong or correct the fiddle.
Thanks ^_^
Andy
Clarification:
The model item has id 1 already selected. I need the list to preselect the option with id 1 in this case. Also, When the option is selected it does not set the item.id to an int, rather it sets it to the entire option item. I need it to set the item.id to the option.Id

<select ng-model="item.id" ng-options="option.id as option.Text for option in options" ng-change='selectChange()'>
You want to select option.id, not option and track by is unnecessary.

Bind the select to ng-model="item", not ng-model="item.id".
Also decide on id vs. Id
<div ng-app="myApp">
<div ng-controller="myctrl">
<select ng-model="item" ng-options="option.Text for option in options track by option.Id" ng-change='selectChange()'>
</select>
</div>
</div>
angular.module('myApp', [])
.controller('myctrl', ['$scope', function($scope) {
$scope.item = {
Id: 1
};
$scope.options = [{
Text: "zero",
Id: 0
}, {
Text: "one",
Id: 1
}, {
Text: "two",
Id: 2
}, {
Text: "three",
Id: 3
}, ];
$scope.selectChange = function() {
console.log ($scope.item.Id)
alert($scope.item.Id);
};
}]);
See here for a fixed version: https://jsfiddle.net/ax3k418p/

https://jsfiddle.net/vb2xe1mc/10/
You need to bind item to ng-model, and inititally $scope.Id should be set to 1 not $scope.id = 1
Also check when you alert it should be alert($scope.item.Id);
<div ng-app="myApp">
<div ng-controller="myctrl">
<select ng-model="item" ng-options="option.Text for option in options" ng-change='selectChange()'>
</select>
</div>
</div>
JS:
angular.module('myApp', [])
.controller('myctrl', ['$scope', function($scope) {
$scope.item = {
Id: 1
};
$scope.options = [{
Text: "zero",
Id: 0
}, {
Text: "one",
Id: 1
}, {
Text: "two",
Id: 2
}, {
Text: "three",
Id: 3
}, ];
$scope.selectChange = function() {
alert($scope.item.Id);
};
}]);

Related

Unable to set selected option in dropdown control

I am unable to bind selected option in dropdown control. I don't want whole object of $scope.Types inside $scope.obj. It should just have value of $scope.Types inside $scope.obj.type
var app = angular.module("myApp", []);
app.controller("MyController", function($scope) {
$scope.types =
[
{ label: "Pizza", value: 1 },
{ label: "Cakes", value: 2 },
{ label: "Pastry", value: 3 }
];
$scope.obj = { type : 1 };//I want dropdown selected value to be updated in type variable
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="myApp" ng-controller="MyController">
<select name="status" ng-model="obj.value"
ng-options="type.value as type.label for type in types track by type.value">
<option value="">Select Types</option>
</select>
</ul>
I am not getting what wrong I am doing here.
var app = angular.module("myApp", []);
app.controller("MyController", function($scope) {
$scope.obj = {};
$scope.types =
[
{ label: "Pizza", value: 1 },
{ label: "Cakes", value: 2 },
{ label: "Pastry", value: 3 }
];
$scope.obj.value = 2;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="myApp" ng-controller="MyController">
<select name="status" ng-model="obj.value"
ng-options="type.value as type.label for type in types">
<option value="">Select Types</option>
</select>
</ul>
Like this?
var app = angular.module("myApp", []);
app.controller("MyController", function($scope) {
$scope.$watch('selectedValue', function(newValue, oldValue) {
if (newValue){
$scope.obj.type = newValue.value;
}
});
$scope.types =
[
{ label: "Pizza", value: 1 },
{ label: "Cakes", value: 2 },
{ label: "Pastry", value: 3 }
];
$scope.obj = { type: 1 };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="myApp" ng-controller="MyController">
<select name="status" ng-model="selectedValue"
ng-options="type as type.label for type in types track by type.value">
<option value="">Select Types</option>
</select>
{{ obj.type}}
</ul>

Select does not keep the value chosen by user

I'm new on Angular, and i'm pretty stuck on a simple select problem.
i did a simple select which iterate my scope to populate the select, but after a user click on an option (which are well created), my select becomes blank with no selection inside, and if i click it again there are no options visible.
below is my code:
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.searchFilterDispatcher = {};
$scope.searchFilterDispatcher.distributionCode = [{
id: 1,
label: 'dist1'
}, {
id: 2,
label: 'dist2'
}];
});
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<select ng-model="searchFilterDispatcher.distributionCode"
ng-options="item as (item.label | uppercase) for item in
searchFilterDispatcher.distributionCode"
class="form-control"
id="distributionCode">
<option >{{'SELECT_A_VALUE' | translate}}</option>
</select>
Any hint?
You should change your ng-model like following. It works in snippet
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.searchFilterDispatcher = {};
$scope.searchFilterDispatcher.distributionCode = [{
id: 1,
label: 'dist1'
}, {
id: 2,
label: 'dist2'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-model="val" ng-options="item as (item.label | uppercase) for item in searchFilterDispatcher.distributionCode" class="form-control" id="distributionCode">
</select>
</div>

Angularjs: update select options

I have two select menus . One for country selection and other for state. I need to update states based country selected. I am able to log states but not able to list them in select menu.Please help.
Angular:
angular.module('demoApp', []).controller('DemoController', function($scope) {
$scope.countries = [
{ label: 'Please select', value: 0 },
{ label: 'India', value: 1 },
{ label: 'US', value: 2 }
];
$scope.data = [{'1':[{ label: 'Delhi', value: 0 },{ label: 'Mumbai', value: 1 },{ label: 'Chennai', value: 2 }]},
{'2':[{ label: 'Alabama', value: 3 },{ label: 'Alaska', value: 4 },{ label: 'Arizona', value: 5 }]}];
$scope.vm = {states: []};
$scope.updateStates = function(countryCode){
$scope.vm.states = $scope.data[countryCode-1];
console.log($scope.vm.states);
};
$scope.correctlySelected = $scope.countries[0];
});
HTML:
<body ng-app="demoApp">
<div ng-controller="DemoController">
<select ng-model="correctlySelected" ng-change="updateStates(correctlySelected.value)" ng-options="opt as opt.label for opt in countries">
</select>
<select ng-options="opt as opt.label for opt in vm.states">
</select>
</div>
</body>
JS Bin:
http://jsbin.com/pafosewedo/1/edit?html,js,console,output
You need to add ng-model to your states <select> - this is required when you are using ng-options
You also have an inconvenient model for the states data. Each element of the data array that corresponds to the country's states is an object with a changing key whose value is an array of states. You could make it work, but it's better to change it to something more reasonable:
$scope.data = {
1: [{ label: 'Delhi', value: 0 }, {...}, ],
2: [{...}, {...}, ] // same for US
}
Then it would work with how you specified your ng-options for states, and you wouldn't have to deal with indices:
$scope.updateStates = function(countryCode){
$scope.vm.states = $scope.data[countryCode]; // access by property
};
I think, that you should use some filter like that if you don't want to change your model:
.filter('stateFilter', function() {
return function(states, countryID) {
var filtered = [];
angular.forEach(states, function(state){
if(state.value === countryID)
filtered.push(state);
});
return filtered;
};
});
to filter out all values that have value equal to selected country.value in first select control.
To use that filter you need to modify your ng-repeat directive value in state select control:
ng-options="state as state.label for data | stateFilter:correctlySelected"
I came up with the following solution, view my JSBin
This solutions works by setting the countryCode in the scope when we are updatingStates.
$scope.updateStates = function(countryCode){
$scope.countryCode = countryCode;
$scope.vm.states = $scope.data[countryCode-1];
console.log($scope.vm.states[countryCode]);
};
This change is then reflected in the view.
<select>
<option ng-repeat='i in vm.states[countryCode]'> {{i.label}}
</option>
</select>

set selected value for select element angularJS

My code is like this
<body ng-app="myApp" ng-controller="MainCtrl">
<select data-ng-model="myclass" data-ng-options="color.name for color in colors">
<option value="">-- Select Freight Class --</option>
</select>
</body>
angular.module('myApp', []).controller('MainCtrl', [
'$http', '$scope', '$filter', function ($http, $scope, $filter) {
$scope.myclass = {
"name": "65"
};
$scope.colors = [{
name: '50'
}, {
name: '55'
}, {
name: '105'
}, {
name: '110'
}, {
name: '400'
}, {
name: '500'
}];
}]);
as you can see I am trying to set default selected value of this select as 65 but its not working. Can any one tell me how to achieve this?
http://jsfiddle.net/d8kg0uys/
First of all you don't have {"name": "65"} object in colors array at all. But even if you tried to select option {"name": "55"} it would not work. And the reason is because $scope.myclass is not equal to any element in colors array.
Angular compares objects to set corresponding option as selected, and one object equals to another only when it's the same object. So to correctly set selected value you have to provide a reference to an object in colors array:
$scope.myclass = $scope.colors[1];
You can do that by:
$scope.myclass = $scope.colors[1];
please see here http://jsfiddle.net/9d0f8sdj/1/
You are binding an object to the ng-model, not the object's field. Not that that is bad but comparing objects in javascript is not as simple as it is in other languages. https://stackoverflow.com/a/1144249/1264360
Also 65 is not in your options list so it is defaulting to the default value.
<select data-ng-model="myclass.name" data-ng-options="color.name as color.name for color in colors">
<option value="">-- Select Freight Class --</option>
</select>
http://plnkr.co/edit/YLFgjILNUC0RP2aBAT6q?p=preview
See AngularJS Reference for Select; You do this by selecting the index of the value you want:
angular
.module('myApp', [])
.controller('MainCtrl', ['$http', '$scope', '$filter',
function ($http, $scope, $filter) {
$scope.colors = [{
name: '50'
}, {
name: '55'
}, {
name: '65'
}, {
name: '105'
}, {
name: '110'
}, {
name: '400'
}, {
name: '500'
}];
$scope.myclass = $scope.colors[2];
}]);
So, the value you want should also be in the $scope.colors list, like I added it above.
Your fiddle corrected: http://jsfiddle.net/d8kg0uys/1/

How to set a default ngOptions value, when options are objects, and default is an integer ID

I'm working with ngOptions to display a select element, and want to connect the model to the value that's set as the value in ngOptions.
var app = angular.module('test', []);
app.controller('TestCtrl', ['$scope',
function ($scope) {
//Use random to simulate different data from an API
$scope.default = Math.floor(Math.random()*3);
$scope.options = [
{
id: 0,
name: "Option 1"
},
{
id: 1,
name: "Option 2"
},
{
id: 2,
name: "Option 3"
}
];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="TestCtrl">
<select ng-model="default" ng-options="val.name for val in options track by val.id">
</select>
<pre>Default should be ID {{default}}, or Option {{default+1}}
</div>
</div>
I've tried using track by, select as, and I've found two solutions that work, but are not ideal.
Ideally, I'd be able to set default
Solution 1:
// Loop through entire array of objects
$scope.options.forEach(function (v, k) {
// Compare ID to what the default should be
if (v.id === $scope.default) {
// Set object to default
$scope.default = v;
return true;
}
});
Solution 2:
JS
$scope.options = {
"Option 1": 0,
"Option 2": 1,
"Option 3": 2
};
HTML
<select ng-model="default" ng-options="value as key for (key, val) in options">
The thing that's tough about this solution is it only works if the object has no more than two values, since a key cannot be an object.
Is there any way to have Angular set a default by key, without having to include the entire object?
try it like this
<select ng-options="item.id as item.name for item in options" ng-model="selected"></select>
then in controller
$scope.selected = 1;
similar plunkr example
var app = angular.module('test', []);
app.controller('TestCtrl', ['$scope',
function ($scope) {
//Use random to simulate different data from an API
$scope.options = [
{
id: 0,
name: "Option 1"
},
{
id: 1,
name: "Option 2"
},
{
id: 2,
name: "Option 3"
}
];
$scope.default = $scope.options[Math.floor(Math.random()*3)];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="TestCtrl">
<select ng-model="default" ng-options="val.name for val in options">
</select>
<pre>Default should be ID {{default.id}}, or Option {{default.id+1}}
</div>
</div>

Categories

Resources