Please look at the following jsbin. I have a select input that has two options (Ohio, NewYork). Within the ng-options for the Select, I am selecting the entire object and NOT just the name or key value. I need both.
When I select Ohio (for example), the model correctly updates showing the selected object:
"birthState": {
"Key": "1",
"Value": "Ohio"
}
If I add this code to the model within my controller (setting the field to 'Ohio' by default), the select does not reflect this default setting.
What am I doing wrong that is preventing me from giving this dropdown a default value?
You are not able to select because, all objects will have unique id. objects in options array and object assigned in model (in controller) will be different in this way.
To achieve what you wanted, try adding track by option.Key in ng-options, and assign Key for 'birthState' field of model inside controller.
<script type="text/ng-template" id="select.html">
<select required type="number" ng-model="model[options.key]" ng-options="option.Value for option in to.options track by option.Key">
<option value="">Select One</option>
</select>
</script>
inside controller
vm.model = {
"birthState": {Key: '3'}
};
Related
The following code works. My question is whether this is the right way to do it.
The variable devices is an array of objects and when the user selects one the variable selDev gets set to one of those objects. If I make selDev the model via the ng-model attribute then it gets a string, not the original model.
<p>
<label>Device Id:</label>
<select ng-model="selDevIndex"
ng-change="selDev = devices[selDevIndex]">
<option value="">(no device)</option>
<option ng-repeat="device in devices "
value="{{$index}}">
{{device.id}}: {{device.type}} {{device.mfr}}
{{device.serial}}
</option>
</select>
</p>
I find this a little clumsy due to the inclusion of the $index reference. Also this technique would not work if devices was an object an not an array. Is there a better way?
You can use ng-options
HTML:
<select ng-model="selectedModel"
ng-options="device as device.text for device in devices track by device.id">
</select>
CONTROLLER:
$scope.selectedModel;
$scope.devices = [{
id: 1,
text: "Device1"
}, {
id: 2,
text: "Device2"
}];
Check this jsFiddle
If you have to loop over an object instead of an array, check this post
Im populating the values and display names for a select based on a JSON call. In the same call, I'm pulling from a nested array to get a default account value (if it exists).
so I have a scope that is holding that default account value, and the select is populating, but for the life of me, I can't figure out how to get the select attribute to apply to the object in the array that has a value that corresponds to the default value.
Essentially, I just want to apply "selected" to the option if the default account ID exists in the array.
Additionally, I cannot change the ng-model of the select because its tied into the form collection function.
Also, Im open to using ng-repeat vs ng-options, just couldn't figure it out with repeat so I moved to the options paradigm.
Any assistance would be grateful!
HTML:
<select class="form-control" id="authQAccount" name="authQAccount" ng-model="authFields.accountID" ng-init ng-options="item as item.name for item in accounts track by item.ID" ng-selected="$scope.defaultAcct" required>
</select>
In my controller:
$http.get('/api/assessment/authorize').success(function(data, status, headers, config) {
$scope.content = data.data;
//Pop the defaults and user options
$scope.languages = [];
angular.forEach(data.data.languages, function(value, key) {
$scope.languages.push(value);
});
$scope.accounts = [];
angular.forEach(data.data.accounts, function(value, key) {
$scope.accounts.push(value);
});
$scope.defaultAcct = data.data.defaultAccount;
The data Im getting:
"data": {
"defaultAccount": "6481004",
"defaultLanguage": "en_us",
"defaultAddonBody": "Test Email for Default",
"accounts": [{
"ID": "6481004",
"name": " ABC Company, Inc. "
}, {
"ID": "6481619",
"name": "EDF Company - Personal "
}
ng-selected only works on option elements and not on the select element itself. I don't think you can achieve what you want here with ng-options, if ng-model isn't set to a matching item then there's no way for the select to have that item selected.
Unless you only want it to appear selected, then you can add <option value="" ng-if="defaultAccount">{{defaultAccountName}}</option>. But then you'd have 2 items for the same value, you could either remove the default account from the list of options or keep the two items but with one of them prefixed as (Default). The second option lets users still select the default option without losing their choice later on, in case the default changes. This also means your form has the default selected without having to change the outer model.
How can I get other properties from loaded json in dropdown / ng-options
On ng-change I also like to pass selected object's campaignType.
How would I able to do that?
My View is looking like this
<div ng-app>
<div ng-controller="cCtrl">
<select ng-model="campaign" ng-options="c.id as c.name for c in campaigns" ng-change="search2(c.campaignType)">
<option value="">-- choose campaign --</option>
</select>
</div>
</div>
My Controller is looking like this
function cCtrl($scope) {
$scope.campaigns = [{
"custID": 1,
"custName": "aaa ",
"msgID": 3,
"msgName": "Email Test Msg",
"id": 2,
"name": "Email Test Campaign",
"description": "Test Campaign",
"campaignType": "Email",
"created": "1374229715",
"isActive": 1,
"isDeleted": 0
}];
$scope.search2 = function (campaignType) {
alert(campaignType); // not working
alert($scope.campaign.campaignType); // not working
//console.log($scope.campaign.campaignType);
}
}
http://jsfiddle.net/webtheveloper/Qgmz7/8/
Instead of passing in a property, you can pass the selected object into the function like this
<select ng-model="campaign" ng-options="c.name for c in campaigns" ng-change="search2(campaign)">
Working Demo
Check this out: http://jsfiddle.net/Qgmz7/9/
You are not in an ngRepeat context. ngOptions works totally different.
ngModel on a <select> will get the value of the <option>, not the whole object. Again, you are not inside an ngRepeat, you don't have access to your objects.
No need to pass the value as parameter, you can get it from $scope. As a matter of fact you don't need ngChange either, you can just $scope.$watch('campaign', ...)
So
$scope.search2 = function () {
console.log($scope.campaign);
}
You can also try it this way (Hack we can say),
<select ng-model="campaign" ng-options="c.id as c.name for c in campaigns" ng-change="search2(campaign,campaigns)">
<option value="">-- choose campaign --</option>
</select>
Basically what this piece of code will do is that it will just pass ng-model along with the whole dropdown list to ng-change.
So in search2 Function, you can just search that ng-model value into that list and get your desired object.
Fiddle for reference : https://jsfiddle.net/vaibhavgavali92/7b7xdyzj/18/
In some cases such as just to display the member value corresponding item selected would not require a call to Controller function. For example if you want to display the campaign type corresponding to selected campaign, it can be written as follow.
<select ng-model="campaign" ng-options="c.name for c in campaigns">
...
<tr><td>Campaign Type:</td><td>{{campaign.campaignType}}</td></tr>
<tr><td>Campaign Description:</td><td>{{campaign.description}}</td></tr>
I have an javascript object as follows in my controller:
$scope.options = [
{
"actualValue": "age",
"displayValue": "Age"
},
{
"actualValue": "maiden",
"displayValue": "Maiden Name"
}
];
Now, I am displaying a select element in which the options of the element will be the values in the "displayValue" property written above:
<select ng-options="entry.displayValue for entry in options" ng-model="biodata">
<options>-- Select a BioData Option --</option>
</select>
Now, my problem is that the ng-model for the select element above when the user select a value from the dropdown is the "displayValue" property. I wish that the ng-model be the "actualValue" property.
How can I achieve this?
<select ng-options="entry.actualValue as entry.displayValue for entry in options"></select>
Fiddle: http://jsfiddle.net/rzV65/
Already answered here: How do I set the value property in AngularJS' ng-options?
I'm trying to render select box and it does not work as expected - options values are incorrect. I checked manual, according to it the syntax for array (in my case array of objects) is
select as label for value in array
So here is what i'm doing:
data:
[{"id":"3","name":"asdasd","code":"asdads","group":"2","cost":"0"},{"id":"4","name":"adrf fg df ","code":"dasfasd","group":"2","cost":"0"}]
template:
<select ng-model="productToBuy" ng-options="item.id as item.id for item in products"></select>
rendered result:
<select ng-model="productToBuy" ng-options="item.id as item.id for item in products" class="ng-pristine ng-valid">
<option value="0" selected="selected">3</option>
<option value="1">4</option>
</select>
as we can see, options values does not set to items's id.
Also this may be not proper syntax when source is array but i having same results when trying like this:
<select ng-model="productToBuy" ng-options="item.id as item.id for (key, item) in products"></select>
I put this code on jsfiddle. Any help appreciated.
This is the behavior of the ngOptions directive (the output you are seeing, where the value is the index of the item and not the id property that you are trying to pass in from your code sample). ngOptions will data-bind the selected option to the variable that you specified in ngModel. You would then work with your data bound variable instead of the "value" of the option element itself.
Html:
<select ng-model="selected" ng-options="item.name for item in items"></select> {{ selected }}
JS:
$scope.items = [
{"id": "3","name":"asdasd","code":"asdads","group":"2","cost":"0"},
{"id": "4","name":"adrf fg df ","code":"dasfasd","group":"2","cost":"0"}
];
In the above example, $scope.selected would represent the actual selected item. You can then access any of the selected item's properties: $scope.selected.name, $scope.selected.code... etc.
If you needed to preselect an item with the above example, you could do the following:
$scope.items = [
{"id": "3","name":"asdasd","code":"asdads","group":"2","cost":"0"},
{"id": "4","name":"adrf fg df ","code":"dasfasd","group":"2","cost":"0"}
];
$scope.selected = $scope.items[1]; // Pre-selected the 2nd item in your array
If you still need to have full control over your value attributes, you're better off using the ng-repeat directive, but remember if you do this, your selected items won't be data bound to your model.
EDIT: Note on 'select as label for value in array' syntax:
In case its helpful, what your "item.id as item.name for item in products" was doing was actually setting your variable in the ngModel directive to the value you specify in the select portion of the syntax. So what that expression is doing is setting the label as item.name, but binding $scope.selected to the value of item.id, rather than to the entire instance of item itself. So if your first item in the examples above was selected, $scope.selected would be equal to "3". It doesn't actually change the value attribute of the option element itself.
Your datatype in the JSON object for the id is a string and the value of $scope.selected is integer. If you switch one of them to the other it would work fine!
The value of the options will still be 0 and 1, but the databinding of Angular does the trick for you and binds the value you have specified in your expression (item.id as item.name) to the ng-model of your parent element (the select element).
If you don't need ng-model of select element and you want to use selected value of select element, then implement it in this way:
<select>
<option ng-repeat="item in items" value="{{item.value}}">
{{item.text}}
</option>
</select>