194

I'm a little bit confused with Angular and ng-options.

I have a simple array and I want to init a select with it. But, I want that options value = label.

script.js

$scope.options = ['var1', 'var2', 'var3'];

html

<select ng-model="myselect" ng-options="o for o in options"></select>

What I get:

<option value="0">var1</option>
<option value="1">var2</option>
<option value="2">var3</option>

What I want:

<option value="var1">var1</option>
<option value="var2">var2</option>
<option value="var3">var3</option>

So I tried:

<select ng-model="myselect2" ng-init=0 ng-options="options[k] as v for (k,v) in options"></select>

<select ng-model="myselect3" ng-init=0 ng-options="b as b for b in options"></select>

(But it didn’t work.)

Edit:

My form is submitted externally, which is why I need 'var1' as the value instead of 0.

Victor Marchuk
  • 13,045
  • 12
  • 43
  • 67
Dragu
  • 3,242
  • 2
  • 16
  • 15

5 Answers5

312

You actually had it correct in your third attempt.

 <select ng-model="myselect" ng-options="o as o for o in options"></select>

See a working example here: http://plnkr.co/edit/xEERH2zDQ5mPXt9qCl6k?p=preview

The trick is that AngularJS writes the keys as numbers from 0 to n anyway, and translates back when updating the model.

As a result, the HTML will look incorrect but the model will still be set properly when choosing a value. (i.e. AngularJS will translate '0' back to 'var1')

The solution by Epokk also works, however if you're loading data asynchronously you might find it doesn't always update correctly. Using ngOptions will correctly refresh when the scope changes.

James Davies
  • 9,602
  • 5
  • 38
  • 42
  • 1
    You're off topic. You didn't understand the instructions. He want `value` in his `select`. – EpokK Aug 13 '13 at 06:41
  • 10
    I understood the instructions, however it's quite likely his intent is to bind the 'value' to the model, and is misunderstanding what's happening due to the way AngularJs is rendering the tag. – James Davies Aug 13 '13 at 06:42
  • 3
    It works if you get select's value with angular, but in my case (ie classic submit form), values will be 0,1,2,3, not var1,var2,var3 – Dragu Aug 13 '13 at 06:45
  • 1
    I assumed you were binding to the model, but if you're simply using AngularJS to render a form submitted externally to angular, then use EpokK's solution. – James Davies Aug 13 '13 at 06:46
  • Question was pretty clear, but I figured there was a good chance you were simply wanting to bind to the model, and looking at the rendered HTML assuming you were getting the ngOptions statement wrong, when you were in fact correct. – James Davies Aug 13 '13 at 06:56
  • o for o in options is enough – Toolkit Aug 13 '14 at 09:13
  • 71
    Is it just me, or is this the most jacked-up and unclear syntax ever? – fool4jesus Nov 11 '14 at 03:09
  • 1
    Not just you. It makes sense once you understand it, but it could be a lot nicer. – James Davies Nov 11 '14 at 06:21
  • 1
    It does not work for me. I am getting 0, 1, 2, .. etc in the options text. – vijayst Jan 24 '15 at 10:31
  • @JamesDavies thanks. your answer doesnt solve Dragus question, but solves mine. :) – robsonrosa Jun 09 '15 at 17:48
  • is there any way to get the actual value instead of the index. – sac Dahal Jul 06 '16 at 13:00
  • I don't like this solution because it does not preselect the options if you init `$scope.myselect = 0;`. You can init with `$scope.myselect = 'var1';` but e.g. if you reload from a database you have to map the value first. – Andi Giga Oct 18 '17 at 08:11
  • So I would go for an array of json objects: http://plnkr.co/edit/Fie2LFbVwncN69RM1pPV?p=preview if data needs to be reloaded. – Andi Giga Oct 18 '17 at 08:21
35

You can use ng-repeat with option like this:

<form>
    <select ng-model="yourSelect" 
        ng-options="option as option for option in ['var1', 'var2', 'var3']"
        ng-init="yourSelect='var1'"></select>
    <input type="hidden" name="yourSelect" value="{{yourSelect}}" />
</form>

When you submit your form you can get value of input hidden.


DEMO

ng-selected ng-repeat

EpokK
  • 38,062
  • 9
  • 61
  • 69
24

If you setup your select like the following:

<select ng-model="myselect" ng-options="b for b in options track by b"></select>

you will get:

<option value="var1">var1</option>
<option value="var2">var2</option>
<option value="var3">var3</option>

working fiddle: http://jsfiddle.net/x8kCZ/15/

Ida N
  • 1,901
  • 22
  • 21
22

you could use something like

<select ng-model="myselect">
    <option ng-repeat="o in options" ng-selected="{{o==myselect}}" value="{{o}}">
        {{o}}
    </option>
</select>

using ng-selected you preselect the option in case myselect was prefilled.

I prefer this method over ng-options anyway, as ng-options only works with arrays. ng-repeat also works with json-like objects.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
iPirat
  • 2,197
  • 1
  • 17
  • 30
10
<select ng-model="option" ng-options="o for o in options">

$scope.option will be equal to 'var1' after change, even you see value="0" in generated html

plunker

Toolkit
  • 10,779
  • 8
  • 59
  • 68