AngularJS - value attribute to select

JSON source data:

[ {"name":"Alabama","code":"AL"}, {"name":"Alaska","code":"AK"}, {"name":"American Samoa","code":"AS"}, ... ] 

I'm trying to

 ng-options="i.code as i.name for i in regions" 

but I get:

 <option value="?" selected="selected"></option> <option value="0">Alabama</option> <option value="1">Alaska</option> <option value="2">American Samoa</option> 

while I expect to receive:

 <option value="AL">Alabama</option> <option value="AK">Alaska</option> <option value="AS">American Samoa</option> 

So, how to get the attributes of value and get rid of "?" paragraph?

By the way, if I set $ scope.regions to static JSON instead of the result of the AJAX request, the empty element will disappear.

+70
angularjs select options
Dec 10 2018-12-12T00:
source share
8 answers

What you first tried should work, but HTML is not what we expect. I added a parameter to handle the initial case of "no elements":

 <select ng-options="region.code as region.name for region in regions" ng-model="region"> <option style="display:none" value="">select a region</option> </select> <br>selected: {{region}} 

The above HTML code:

 <select ng-options="..." ng-model="region" class="..."> <option style="display:none" value class>select a region</option> <option value="0">Alabama</option> <option value="1">Alaska</option> <option value="2">American Samoa</option> </select> 

Fiddle

Even if Angular uses numeric integers for the value, the model (i.e. $ scope.region) will be set to AL, AK, or AS, if required. (The numeric value is used by Angular to find the correct array entry when an option is selected in the list.)

This can be confusing when you first learn how Angular implements its select directive.

+72
Dec 10 '12 at 20:33
source share

You cannot do this unless you yourself create them in ng-repeat.

 <select ng-model="foo"> <option ng-repeat="item in items" value="{{item.code}}">{{item.name}}</option> </select> 

BUT ... it's probably not worth it. It is better to leave it a function in accordance with the design and allow Angular to handle internal work. Angular uses this index so that you can actually use the whole object as a value. So you can use the drop down binding to select an integer value, not just a string, which is pretty surprising:

 <select ng-model="foo" ng-options="item as item.name for item in items"></select> {{foo | json}} 
+25
Dec 10
source share

If you use the track by parameter, the value attribute is value correctly, for example:

 <div ng-init="a = [{label: 'one', value: 15}, {label: 'two', value: 20}]"> <select ng-model="foo" ng-options="x for x in a track by x.value"/> </div> 

gives:

 <select> <option value="" selected="selected"></option> <option value="15">one</option> <option value="20">two</option> </select> 
+21
Jul 30 '14 at 14:25
source share

If the model specified for the drop-down list does not exist, then angular will generate an empty element. Thus, you will need to explicitly point the model to select as follows:

 <select ng-model="regions[index]" ng-options="...."> 

Pay attention to the following, as was answered earlier:

Why does AngularJS have an empty option in the selection? and this is fiddle

Update: Try this instead:

 <select ng-model="regions[index].code" ng-options="i.code as i.name for i in regions"> </select> or <select ng-model="regions[2]" ng-options="r.name for r in regions"> </select> 

Note that there is no empty element in the select item.

+6
Dec 10
source share

You can change the model to look like this:

 $scope.options = { "AL" : "Alabama", "AK" : "Alaska", "AS" : "American Samoa" }; 

Then use

 <select ng-options="k as v for (k,v) in options"></select> 
+5
Dec 10 '12 at 15:38
source share

It seems that it is virtually impossible to use the β€œvalue” of the selection in any meaningful way as a regular HTML form element, and also connect it to Angular in an approved way using ng-options. As a compromise, I had to put a hidden input next to my choice, and it keeps track of the same model as my choice, like this (all this is very simplified from real production code for short):

HTML:

 <select ng-model="profile" ng-options="o.id as o.name for o in profiles" name="something_i_dont_care_about"> </select> <input name="profile_id" type="text" style="margin-left:-10000px;" ng-model="profile"/> 

JavaScript:

 App.controller('ConnectCtrl',function ConnectCtrl($scope) { $scope.profiles = [{id:'xyz', name:'a profile'},{id:'abc', name:'another profile'}]; $scope.profile = -1; } 

Then in my server code, I just looked for params[:profile_id] (it was a Rails application, but the same principle applies anywhere). Since the hidden input tracks the same model as the selection, they remain synchronized automatically (no additional javascript is required for this). This is the coolest part of Angular. This almost compensates for what it does with the value attribute as a side effect.

Interestingly, I found that this method only worked with input tags that were not hidden (so I had to use margin-left: -10000px; a trick to move input from the page). These two options did not help:

 <input name="profile_id" type="text" style="display:none;" ng-model="profile"/> 

and

 <input name="profile_id" type="hidden" ng-model="profile"/> 

I feel this should mean that I'm missing something. It seems too strange that this is a problem with Angular.

+4
Aug 29 '13 at 5:02
source share

you can use

 state.name for state in states track by state.code 

In the case of states in the JSON array, state is the name of the variable for each object in the array.

Hope this helps

+1
Oct 21 '14 at 6:35
source share

Try as below:

 var scope = $(this).scope(); alert(JSON.stringify(scope.model.options[$('#selOptions').val()].value)); 
-2
Dec 22 '14 at 3:26
source share



All Articles