HTML select
element with AngularJS data-binding.
The select
directive is used together with ngModel
to provide data-binding
between the scope and the <select>
control (including setting default values).
It also handles dynamic <option>
elements, which can be added using the ngRepeat
or
ngOptions
directives.
When an item in the <select>
menu is selected, the value of the selected option will be bound
to the model identified by the ngModel
directive. With static or repeated options, this is
the content of the value
attribute or the textContent of the <option>
, if the value attribute is missing.
Value and textContent can be interpolated.
The select controller exposes utility functions that can be used to manipulate the select's behavior.
In general, the match between the model and an option is evaluated by strictly comparing the model value against the value of the available options.
If you are setting the option value with the option's value
attribute, or textContent, the
value will always be a string
which means that the model value must also be a string.
Otherwise the select
directive cannot match them correctly.
To bind the model to a non-string value, you can use one of the following strategies:
ngOptions
directive
(select
)ngValue
directive, which allows arbitrary expressions to be
option values (Example)If the viewValue of ngModel
does not match any of the options, then the control
will automatically add an "unknown" option, which it then removes when the mismatch is resolved.
Optionally, a single hard-coded <option>
element, with the value set to an empty string, can
be nested into the <select>
element. This element will then represent the null
or "not selected"
option. See example below for demonstration.
ngRepeat
and ngOptions
In many cases, ngRepeat
can be used on <option>
elements instead of ngOptions to achieve a similar result. However, ngOptions
provides some benefits:
<select>
's model is assigned via the select
as
part of the
comprehension expressionSpecifically, select with repeated options slows down significantly starting at 2000 options in Chrome and Internet Explorer / Edge.
<select
ng-model="string"
[name="string"]
[multiple="string"]
[required="string"]
[ng-required="string"]
[ng-change="string"]
[ng-options="string"]
[ng-attr-size="string"]>
...
</select>
Param | Type | Details |
---|---|---|
ngModel | string |
Assignable AngularJS expression to data-bind to. |
name
(optional)
|
string |
Property name of the form under which the control is published. |
multiple
(optional)
|
string |
Allows multiple options to be selected. The selected values will be bound to the model as an array. |
required
(optional)
|
string |
Sets |
ngRequired
(optional)
|
string |
Adds required attribute and required validation constraint to the element when the ngRequired expression evaluates to true. Use ngRequired instead of required when you want to data-bind to the required attribute. |
ngChange
(optional)
|
string |
AngularJS expression to be executed when selected option(s) changes due to user interaction with the select element. |
ngOptions
(optional)
|
string |
sets the options that the select is populated with and defines what is
set on the model on selection. See |
ngAttrSize
(optional)
|
string |
sets the size of the select element dynamically. Uses the ngAttr directive. |
select
elements with static options
<div ng-controller="ExampleController">
<form name="myForm">
<label for="singleSelect"> Single select: </label><br>
<select name="singleSelect" ng-model="data.singleSelect">
<option value="option-1">Option 1</option>
<option value="option-2">Option 2</option>
</select><br>
<label for="singleSelect"> Single select with "not selected" option and dynamic option values: </label><br>
<select name="singleSelect" id="singleSelect" ng-model="data.singleSelect">
<option value="">---Please select---</option> <!-- not selected / blank option -->
<option value="{{data.option1}}">Option 1</option> <!-- interpolation -->
<option value="option-2">Option 2</option>
</select><br>
<button ng-click="forceUnknownOption()">Force unknown option</button><br>
<tt>singleSelect = {{data.singleSelect}}</tt>
<hr>
<label for="multipleSelect"> Multiple select: </label><br>
<select name="multipleSelect" id="multipleSelect" ng-model="data.multipleSelect" multiple>
<option value="option-1">Option 1</option>
<option value="option-2">Option 2</option>
<option value="option-3">Option 3</option>
</select><br>
<tt>multipleSelect = {{data.multipleSelect}}</tt><br/>
</form>
</div>
angular.module('staticSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
singleSelect: null,
multipleSelect: [],
option1: 'option-1'
};
$scope.forceUnknownOption = function() {
$scope.data.singleSelect = 'nonsense';
};
}]);
ngRepeat
to generate select
options
<div ng-controller="ExampleController">
<form name="myForm">
<label for="repeatSelect"> Repeat select: </label>
<select name="repeatSelect" id="repeatSelect" ng-model="data.model">
<option ng-repeat="option in data.availableOptions" value="{{option.id}}">{{option.name}}</option>
</select>
</form>
<hr>
<tt>model = {{data.model}}</tt><br/>
</div>
angular.module('ngrepeatSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
model: null,
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
]
};
}]);
ngValue
to bind the model to an array of objects
<div ng-controller="ExampleController">
<form name="myForm">
<label for="ngvalueselect"> ngvalue select: </label>
<select size="6" name="ngvalueselect" ng-model="data.model" multiple>
<option ng-repeat="option in data.availableOptions" ng-value="option.value">{{option.name}}</option>
</select>
</form>
<hr>
<pre>model = {{data.model | json}}</pre><br/>
</div>
angular.module('ngvalueSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
model: null,
availableOptions: [
{value: 'myString', name: 'string'},
{value: 1, name: 'integer'},
{value: true, name: 'boolean'},
{value: null, name: 'null'},
{value: {prop: 'value'}, name: 'object'},
{value: ['a'], name: 'array'}
]
};
}]);
select
with ngOptions
and setting a default valueSee the ngOptions documentation for more ngOptions
usage examples.
<div ng-controller="ExampleController">
<form name="myForm">
<label for="mySelect">Make a choice:</label>
<select name="mySelect" id="mySelect"
ng-options="option.name for option in data.availableOptions track by option.id"
ng-model="data.selectedOption"></select>
</form>
<hr>
<tt>option = {{data.selectedOption}}</tt><br/>
</div>
angular.module('defaultValueSelect', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.data = {
availableOptions: [
{id: '1', name: 'Option A'},
{id: '2', name: 'Option B'},
{id: '3', name: 'Option C'}
],
selectedOption: {id: '3', name: 'Option C'} //This sets the default value of the select in the ui
};
}]);
select
to a non-string value via ngModel
parsing / formatting
<select ng-model="model.id" convert-to-number>
<option value="0">Zero</option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
{{ model }}
angular.module('nonStringSelect', [])
.run(function($rootScope) {
$rootScope.model = { id: 2 };
})
.directive('convertToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(val) {
return parseInt(val, 10);
});
ngModel.$formatters.push(function(val) {
return '' + val;
});
}
};
});
it('should initialize to model', function() {
expect(element(by.model('model.id')).$('option:checked').getText()).toEqual('Two');
});