Angularjs ngOption with array - angularjs

I want to add an html select with options AM,PM with angularjs,
what i need is having the key and the value of the option be the same :
<option value="AM">AM</option>
<option value="PM">PM</option>
My html looks like this
<select ng-model="ampm" ng-options="k as v for (k , v) in ampms"></select>
and my controller looks like
$scope.ampm = (new Date().getHours()) >= 12 ? 'PM' : 'AM';
$scope.ampms ={"AM":"AM","PM":"PM"};
and every thing working fine.
My question is why i cant have the same thing when i used an array (i tried all the options in the ng-options)
as this
$scope.ampms =["AM","PM"];
what ever i do i always get this
<option value="0">AM</option>
<option value="1">PM</option>
What i want is using an array like above with the option has the key and the value the same.

With AngularJS, you don't need to worry about what the value of the option is. All the selects I've seen with ng-options have values of 0 through whatever. If you're just looking for a dropdown with the two options, it can be as simple as
<select ng-model="ampm" ng-options="currOption for currOption in ['AM', 'PM']"></select>
See http://jsfiddle.net/EyBVN/1/

This is is a default behavior of ng-options in Angular. If you do not specify a key name, angular will automatically choose to use the index rather than a key. The code that does that can be seen on line 405 in /src/ng/directives/select.js on Angular's Github repository.
It can't even be forced by "value as value for (index, value) in values".
But as dnc253 just beat me to the punch with his answer (it showed up while I was typing)... you don't have to worry about it, Angular does it all for you automatically.

I did find a way to place specific data in the value of the options for a select. You have to add an ng-repeat attribute to the option tag inside the select tag:
<select id="{{question.id}}" name="{{question.id}}"
class="{{question.inputclass}}" ng-required="question.required"
title="{{question.title}}">
<option value=""></option>
<optgroup ng-repeat="group in question.data" label="{{group.group}}">
<option ng-repeat="item in group.data" value="{{item.value}}"
ng-selected="{{item.value == question.defaultValue}}">
{{item.description}}
</option>
</optgroup>
</select>
As a bonus, I left the option group tags in place to serve as an example for everyone.
The question.data JSON is:
[
{"group":"Canada","data":[{"value":"Ontario","description":"Toronto"},
{"value":"Quebec","description":"Quebec City"},
{"value":"Manitoba","description":"Winnipeg"}
]
},
{"group":"Mexico","data":[{"value":"Jalisco","description":"Guadalajara"},
{"value":"Nayarit","description":"Tepic"}
]
},
{"group":"United States of America","data":[
{"value":"Alabama","description":"Montgomery"},
{"value":"Georgia","description":"Atlanta"},
{"value":"Mississippi","description":"Jackson"},
{"value":"Louisiana","description":"Baton Rouge"},
{"value":"Texas","description":"Ausint"}
]
}
]

Related

ng-options is only working for name, not value

I've seen a few questions here similar to this. In fact that's how I got this far. But one little piece isn't working. I have the following:
<select id="facility" class="form-control"
ng-model="MainObj.facility" name="facility"
ng-options="fclty.value as fclty.name for fclty in MainData.fclts">
<option value=""></option>
</select>
I've checked via logging that MainData.fclts contains exactly what I want, but each option outputs as
<option value="0" label="Actual Facility Name">Actual Facility Name</option>
<option value="1" label="Actual Facility Name">Actual Facility Name</option>
(etc)
In other words, it's putting the name in there correctly, but just using a 0, 1, 2, ... for the value instead of what's in the value field.
What am I missing here?
Thanks.
EDIT:
Sample data:
[value: '00001', name: "John's House"]
[value: '00002', name: "School"]
[value: 'testval', name: "Testing Building"]
(etc)
EDIT 2:
Just for the fun of it, I swapped the two and did fclty.name as fclty.value. Sure enough the value showed up in the dropdown but the value portion of the option was still the default 0, 1, 2, ..
So, it can SEE that field if it wants to, but, for some reason, doesn't want to use it to fill in the value of the option.
What does your MainObj and MainData look like? This example works exactly as it should:
angular.module("myApp",[])
.controller("main",["$scope", function($scope){
$scope.MainData = {
fclts: [
{name:"Place", value: "00001"},
{name:"Other Place", value: "00002"},
{name:"Thrid Place", value: "testval"}
]
};
$scope.MainObj = {facility: "00002"};
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<body ng-app="myApp" ng-controller="main">
<select ng-model="MainObj.facility" name="facility" ng-options="fclty.value as fclty.name for fclty in MainData.fclts">
</select>
{{MainObj.facility}}
</body>
Your sample data is not in valid syntax, please confirm that they are formatted like objects:
[
{value: "00001", name: "John's House"},
{value: "00002", name: "School"},
{name:"Thrid Place", value: "testval"}
]
With AngularJS V1.3, the ng-options directive sets the value to the $index of the option.
<option value="" class=""></option>
<option value="0" label="John's House">John's House</option>
<option value="1" label="School">School</option>
<option value="2" label="Testing Building">Testing Building</option>
With AngularJS V1.4, the ng-options directive sets the value differently:
<option value="" class=""></option>
<option label="John's House" value="string:00001">John's House</option>
<option label="School" value="string:00002">School</option>
<option label="Testing Building" value="string:testval">Testing Building</option>
Between V1.3 and V1.4, the ng-options directive underwent major refactoring.
From the Docs:
ngOptions
The ngOptions directive has also been refactored and as a result some long-standing bugs have been fixed. The breaking changes are comparatively minor and should not affect most applications.
Due to 7fda214c, when ngOptions renders the option values within the DOM, the resulting HTML code is different. Normally this should not affect your application at all, however, if your code relies on inspecting the value property of <option> elements (that ngOptions generates) then be sure to read the details.
Due to 7fda214c, when iterating over an object's properties using the (key, value) in obj syntax the order of the elements used to be sorted alphabetically. This was an artificial attempt to create a deterministic ordering since browsers don't guarantee the order. But in practice this is not what people want and so this change iterates over properties in the order they are returned by Object.keys(obj), which is almost always the order in which the properties were defined.
Also due to 7fda214c, setting the ngOptions attribute expression after the element is compiled, will no longer trigger the ngOptions behavior. This worked previously because the ngOptions logic was part of the <select> directive, while it is now implemented in the ngOptions directive itself.
— AngularJS Developer Guide - Migrating from V1.3 to V1.4 - ngOptions

angularjs ng-model(s) $scope

I'm quite new in AngularJs, I just started to learn this World today. I think I got the point, but I do not understand the next problem.
I have a site which contains a lot of select input fields. I will explain my problem with two select fields
********** THE HTML FILE *************
enter code here
<div id="FormContainer" ng-app="PermissionsApp">
<div class="permission_container" ng-controller="PermsCtrl">
<select id="select_all" ng-model="select_all_var" ng-change="UpdateAll()">
<option value="" ng-hide="true">-</option>
<option value="0">-</option>
<option value="n">no</option>
<option value="a" ng-selected="true">all</option>
<option value="g">group</option>
<option value="o">own</option>
</select>
<select id="select_1_1" ng-model="select_1_1_var" ng-change="Update(1, 1)">
<option value="" ng-hide="true">--</option>
<option value="n">no</option>
<option value="a" ng-selected="true">all</option>
<option value="g">group</option>
<option value="o">own</option>
</select>
</div>
</div>
************** THE JS FILE **************
enter code here
var permissionsApp = angular.module("PermissionsApp", []);
permissionsApp.controller("PermsCtrl",['$scope', function($scope) {
$scope.UpdateAll = function () {
console.log($scope.select_all_var + " - " + $scope.select_1_1_var);
}
$scope.Update = function (modul_id, action_id) {
console.log($scope.select_all_var + " - " + $scope.select_1_1_var);
}
}]);
OK ...
FIRST ISSUE
IF I change FIRST the select_all field after page reload, I get the next on the console: g - undefined
After that I change the select_1_1 field, I get the next on the console: g - g
SECOND ISSUE
If I change FIRST the select_1_1 fieldl after page reload I get the next on the console: undefined - g
After that I change the select_all field, I get the next on the console: g - g
SO ... it seems for me the variables can be seen in the $scope just after the change event .... do I need to declare the variables first time, or what's the problem? But I there are about 200 select fields on the page ... I do not want to declare them one by one.
Thanks for your answers in advance!
FF
So there are 2 ways to fix this:
ng-init
You can initialize your model to the desired value using:
<select ng-model="select_1_1_var"
ng-init="select_1_1_var = 'a'">
I don't use ng-selected much so I'm not familiar with its inner workings, but I would make an educated guess that this works solely on the UI and that it argues with other directives regarding initializing model values.
example - https://plnkr.co/edit/eO60jeXIKlDhAFuopnUc?p=preview
ng-options
So there has been a lacking feature (in my opinion) that you couldn't initialize a select control with a pre-existing model value when declaring your option elements. This is especially problematic when trying to use ng-repeat. It is recommended that you use ng-options and set your options via the controller as well as initialize your model values there:
<select id="select_all"
ng-model="select_all_var"
ng-options="opt.value as opt.name for opt in opts"
ng-change="UpdateAll()">
</select>
example - https://plnkr.co/edit/M4qZEL4Y8EfRtabfSN8a?p=preview
bonus
If you want to display an empty option without muddying up your options array, please visit my answer here - Why does AngularJS include an empty option in select?

Empty Option field in Select tag - Angular js

I am getting empty Option field in select tag.
My code is shown below:
openSelectBoxModel="47"
openSelectList=[{id:""47",name:"text"}];
valuekey="id";
titlekey="name";
<select id="reportOpenSelectBoxSingle" size="6" ng-style='selectStyle' class="openSelectBox" ng-model="openSelectBoxModel" ng-change="changeFn()" >
<option ng-selected="openSelectBoxModel===item[valueKey]" ng-repeat="item in openSelectList" id="" ng-value="{{item[valueKey]}}" ng-title="{{item[titleKey]}}" ng-bind="item[titleKey]"></option>
</select>
Please help me to solve this problem.
You should not use ng-selected with ng-model.
The thing to do is to bind the selected item to your ng-model before displaying it.
//Also, instead of ng-repeat, you should use ng-option
As far as performance is regarded : ng-options does not create child scopes for every iteration. When angular performs its digest, your ng-repeat will slow it. If you have a list with hundreds of elements, you will feel a difference.
<select id="reportOpenSelectBoxSingle"
size="6"
ng-style='selectStyle'
class="openSelectBox"
ng-model="openSelectBoxModel"
ng-change="changeFn()" >
<option ng-repeat="item in openSelectList"
value="{{item[valueKey]}}"
title="{{item[titleKey]}}"
ng-bind="item[titleKey]">
</option>
</select>
Furthermore, you need to declare your variables inside a controller :
$scope.openSelectBoxModel="47";
$scope.openSelectList=[{id:"47",name:"text"}];
$scope.valuekey="id";
$scope.titlekey="name";

Angular Select List Binding an Object when I was expecting a Value

I wonder if I am going about this all wrong, but here's the issue.
I have a Select List configured like so:
<select name="{{ measure.Name }}_MeasureId"
ng-model="CompleteDataSetViewModel.AnnualRecord.TargetHazardousWaste_Original_MeasureId"
ng-options="obj.Text for obj in measure.AnnualTarget_Measure_SelectList track by obj.Value"
ng-init="CompleteDataSetViewModel.AnnualRecord.TargetHazardousWaste_Original_MeasureId = measure.AnnualTarget_Measure_SelectList[measure.InitialFigure_Measure - 1]"
class="" required></select>
This outputs what I want:
<option selected="selected" value="?"></option>
<option value="13">Metric Tonnes </option>
<option value="14">Imperial Tonnes</option>
<option value="15">Short Tonnes </option>
What I then want in my JSON is the value of CompleteDataSetViewModel.AnnualRecord.TargetHazardousWaste_Original_MeasureId to be set to a numeric value of let's say 13. However, what I actually get is an object like this:
"TargetHazardousWaste_Original_MeasureId": {
"Text": "Metric Tonnes ",
"Value": "13",
"Selected": false
},
This is somewhat correct - the right item is picked, but what I am after is simply the 13 as that is the value I want to write to my database.
I have considered doing some kind of mapping exercise to effectively extract the value and assign it, but that feels counter to what Angular appears to be about (I've only been at it 2 days).
I've tried the Angular documentation, but that's left me feeling more confused. Is there something I am missing?
Change your ng-options to this:
obj.Value as obj.Text for obj in measure.AnnualTarget_Measure_SelectList track by obj.Value
Without that, you're making it so the one they select is the entire object.

How bydefault select an Item in - ng-repeat on options through use of model

I am using ng-repeat on option in select.
<select ng-model="mymodel">
<option ng-repeat="p in persons" value="{{p.id}}">{{p.name}}</option>
</select>
$scope.persons= [
{id:1,name:"tester11"},
{id:2,name:'tester22'},
{id:3,name:'tester33'},
{id:4,name:'tester44'}
];
How can I make an option selectable means by default "tester33" should be selected
through use of ng-model.
I know it is achievable through ng-options. But I want to try this one.
Thanks in advance.
There is no perfect way to achieve this using ng-repeat, but here's a workaround:
<select ng-model="mymodel">
<option ng-repeat="p in persons" ng-selected="p.name=='tester33'" value="{{p.id}}">{{p.name}}</option>
</select>
This just sets the option with name='tester33' but the model won't get updated until the user changes select value explicitly
NOTE: This is not a recommended way, you must use ng-options for complete functionality

Resources