I have read about it in other posts, but I couldn\'t figure it out.
I have an array,
$scope.items = [
{ID: \'000001\', Title: \'Chicago\'},
{ID
In CoffeeScript:
#directive
app.directive('select2', ->
templateUrl: 'partials/select.html'
restrict: 'E'
transclude: 1
replace: 1
scope:
options: '='
model: '='
link: (scope, el, atr)->
el.bind 'change', ->
console.log this.value
scope.model = parseInt(this.value)
console.log scope
scope.$apply()
)
<!-- HTML partial -->
<select>
<option ng-repeat='o in options'
value='{{$index}}' ng-bind='o'></option>
</select>
<!-- HTML usage -->
<select2 options='mnuOffline' model='offlinePage.toggle' ></select2>
<!-- Conclusion -->
<p>Sometimes it's much easier to create your own directive...</p>
If you need a custom title for each option, ng-options
is not applicable. Instead use ng-repeat
with options:
<select ng-model="myVariable">
<option ng-repeat="item in items"
value="{{item.ID}}"
title="Custom title: {{item.Title}} [{{item.ID}}]">
{{item.Title}}
</option>
</select>
For some reason AngularJS allows to get me confused. Their documentation is pretty horrible on this. More good examples of variations would be welcome.
Anyway, I have a slight variation on Ben Lesh's answer.
My data collections looks like this:
items =
[
{ key:"AD",value:"Andorra" }
, { key:"AI",value:"Anguilla" }
, { key:"AO",value:"Angola" }
...etc..
]
Now
<select ng-model="countries" ng-options="item.key as item.value for item in items"></select>
still resulted in the options value to be the index (0, 1, 2, etc.).
Adding Track By fixed it for me:
<select ng-model="blah" ng-options="item.value for item in items track by item.key"></select>
I reckon it happens more often that you want to add an array of objects into an select list, so I am going to remember this one!
Be aware that from AngularJS 1.4 you can't use ng-options any more, but you need to use ng-repeat
on your option tag:
<select name="test">
<option ng-repeat="item in items" value="{{item.key}}">{{item.value}}</option>
</select>
It can be useful. Bindings do not always work.
<select id="product" class="form-control" name="product" required
ng-model="issue.productId"
ng-change="getProductVersions()"
ng-options="p.id as p.shortName for p in products"></select>
For example, you fill the options list source model from a REST service. A selected value was known before filling the list, and it was set. After executing the REST request with $http, the list option is done.
But the selected option is not set. For unknown reasons AngularJS in shadow $digest executing does not bind selected as it should be. I have got to use jQuery to set the selected. It`s important! AngularJS, in shadow, adds the prefix to the value of the attr "value" for generated by ng-repeat options. For int it is "number:".
$scope.issue.productId = productId;
function activate() {
$http.get('/product/list')
.then(function (response) {
$scope.products = response.data;
if (productId) {
console.log("" + $("#product option").length);//for clarity
$timeout(function () {
console.log("" + $("#product option").length);//for clarity
$('#product').val('number:'+productId);
}, 200);
}
});
}
The question is already answered (BTW, really good and comprehensive answer provided by Ben), but I would like to add another element for completeness, which may be also very handy.
In the example suggested by Ben:
<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>
the following ngOptions form has been used: select as label for value in array
.
Label is an expression, which result will be the label for <option>
element. In that case you can perform certain string concatenations, in order to have more complex option labels.
Examples:
ng-options="item.ID as item.Title + ' - ' + item.ID for item in items"
gives you labels like Title - ID
ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items"
gives you labels like Title (X)
, where X
is length of Title string.You can also use filters, for example,
ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items"
gives you labels like Title (TITLE)
, where Title value of Title property and TITLE is the same value but converted to uppercase characters.ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items"
gives you labels like Title (27 Sep 2015)
, if your model has a property SomeDate
I hope the following will work for you.
<select class="form-control"
ng-model="selectedOption"
ng-options="option.name + ' (' + (option.price | currency:'USD$') + ')' for option in options">
</select>