-
Notifications
You must be signed in to change notification settings - Fork 1.8k
ui select choices
The ui-select-choices
is what the option
tag is to a html select
element.
option | description | value |
---|---|---|
group-by |
Group by expression | expression |
group-filter |
Filter or sort groups by expression | expression |
ui-disable-choice |
Disable a choice in the menu | expression |
refresh |
Define the source of data as an $http request. ui-select will call this function as dictated by the refresh-delay setting |
string ($scope function) |
refresh-delay |
If the refresh attribute is present, the default delay is set to 1000 . Override this by setting a millisecond value via refresh-delay
|
integer |
minimum-input-length |
Minimum characters required before refresh function is triggered |
integer (or interpolated expression: {{ 1 + 1 }} ) |
position |
Define where the dropdown should open. 'up', 'down' or 'auto'. | string |
repeat |
Specify the list of items to provide as choices. Syntax is similar to ngRepeat . |
expression |
ui-select-header-group-selectable |
Allow user to select header with group-by. The expression is used to disable or enable this feature | expression |
event name | description | example |
---|---|---|
on-highlight |
Occurs when an item was hovered on | on-highlight="showPreview(myValue)" |
In case that you need to disable certain options so that they can't be selected by the interface, you can use ui-disable-choice
attribute to pass an expression to check. For example:
<ui-select ng-model="model.people">
<ui-select-match>{{$select.selected.name}}</ui-select-match>
<ui-select-choices ui-disable-choice="value.status == 'inactive'" repeat="value.id as value in options | filter: $select.search">
<div ng-bind-html="value.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
On the ui-select-choices
define the group-by
property with a string or a function; example: group-by="someGroupFn"
or group-by="'countries'"
. A variable attribute is not valid here, e.g. group-by="myType"
.
The function usage might look something like:
$scope.someGroupFn = function (item){
if (item.name[0] >= 'A' && item.name[0] <= 'M')
return 'From A - M';
if (item.name[0] >= 'N' && item.name[0] <= 'Z')
return 'From N - Z';
};
The function is automatically invoked with the item you are iterating over. Items could be in the same group twice if the function matches them twice.
To sort the groups, the items must already be in order with each type in the proper index given their sort attribute.
If you have 2 groups that are represented in 2 different lists you must merge the lists in order to group them. For example: I have a list of cities and countries that are seperated by the list type. You would have to merge the 2 lists and then use the group by option to filter them.
$scope.displayValues = function() {
return cities.concat(countries);
}();
$scope.groupFind = function(item){
return cities.indexOf(item) > -1 ? "City" : "Country";
};
<ui-select ng-model="animal.names">
<ui-select-match>{{$select.selected.name}}</ui-select-match>
<ui-select-choices group-by="groupFind" repeat="value.id as value in animals | filter: $select.search">
<div ng-bind-html="value.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
If you want some options to have groups and other not, return undefined
as the group in the callback and those will be inserted without a group. For example:
$scope.groupFind = function(item){
return cities.indexOf(item) > -1 ? "City" : undefined;
};
If you want to allow user to select a group, you can add the ui-select-header-group-selectable directive. For example:
<ui-select ng-model="animal.names">
<ui-select-match>{{$select.selected.name}}</ui-select-match>
<ui-select-choices ui-select-header-group-selectable group-by="groupFind" repeat="value.id as value in animals | filter: $select.search">
<div ng-bind-html="value.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
In the repeat
of the ui-select-choices
identify the property you are wanting to bind to; repeat="item.id as item in cards">
.
Example usage:
<ui-select ng-model="card.id">
<ui-select-match>{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="item.id as item in reports | filter: $select.search">
<div ng-bind-html="item.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
If you are using the ui-select-match
search feature, its important to realize that most examples do generic property matching on the object you're iterating. So given an example like:
<ui-select ng-model="card.id">
<ui-select-match>{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="item.id as item in users | filter: $select.search">
<div ng-bind-html="item.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
and the users
object looks like:
[{ name: 'Dan', description: 'Dan is a winner', id: 1234 }]
if you type 'winner' it will pull up 'Dan' but NOT highlight anything since we highlight the display name. You can easily restrict the filter by adding a property name to the filter like:
<ui-select ng-model="card.id">
<ui-select-match>{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="item.id as item in users | filter: { name: $select.search }">
<div ng-bind-html="item.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
The demo page has a good example for OR filters or check out the Angular Documentation for more info on filters.
Use objects for iterating instead of Arrays. Demo here
<ui-select ng-model="person.selectedValue" title="Choose a person">
<ui-select-match placeholder="Select a person in the list or search his name/age...">{{$select.selected.value.name}}</ui-select-match>
<ui-select-choices repeat="person.value as (key, person) in peopleObj | filter: {'value':$select.search}">
<div ng-bind-html="person.value.name | highlight: $select.search"></div>
<small>
email: {{person.value.email}}
age: <span ng-bind-html="''+person.value.age | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
<ui-select ng-model="person.selectedSingle" title="Choose a person">
<ui-select-match placeholder="Select a person in the list or search his name/age...">{{$select.selected.value.name}}</ui-select-match>
<ui-select-choices repeat="person.value.name as (key, person) in peopleObj | filter: {'value':$select.search}">
<div ng-bind-html="person.value.name | highlight: $select.search"></div>
<small>
email: {{person.value.email}}
age: <span ng-bind-html="''+person.value.age | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
<ui-select ng-model="person.selectedSingleKey" title="Choose a person">
<ui-select-match placeholder="Select a person in the list or search his name/age...">{{$select.selected.value.name}}</ui-select-match>
<ui-select-choices repeat="person.key as (key, person) in peopleObj | filter: {'value':$select.search}">
<div ng-bind-html="person.value.name | highlight: $select.search"></div>
<small>
email: {{person.value.email}}
age: <span ng-bind-html="''+person.value.age | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
Note that using select as
and track by
may result in a broken ui-select
. Only one or other should be used.
The following is copied from angular's ngOptions documentation and applies to ui-select-choices
repeat
attrbute.
###
select
as
andtrack by
Be careful when using
select
as
andtrack by
in the same expression.Given this array of items on the $scope:
$scope.items = [{ id: 1, label: 'aLabel', subItem: { name: 'aSubItem' } }, { id: 2, label: 'bLabel', subItem: { name: 'bSubItem' } }];This will work:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>$scope.selected = $scope.items[0];but this will not work:
<select ng-options="item.subItem as item.label for item in items track by item.id" ng-model="selected"></select>$scope.selected = $scope.items[0].subItem;In both examples, the
track by
expression is applied successfully to eachitem
in theitems
array. Because the selected option has been set programmatically in the controller, thetrack by
expression is also applied to thengModel
value. In the first example, thengModel
value isitems[0]
and thetrack by
expression evaluates toitems[0].id
with no issue. In the second example, thengModel
value isitems[0].subItem
and thetrack by
expression evaluates toitems[0].subItem.id
(which is undefined). As a result, the model value is not matched against any<option>
and the<select>
appears as having no selected value.