Asked  7 Months ago    Answers:  5   Viewed   59 times

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: '000002', Title: 'New York'},
   {ID: '000003', Title: 'Washington'},
];

I want to render it as:

<select>
  <option value="000001">Chicago</option>
  <option value="000002">New York</option>
  <option value="000003">Washington</option>
</select>

And also I want to select the option with ID=000002.

I have read select and tried, but I can't figure it out.

 Answers

35

One thing to note is that ngModel is required for ngOptions to work... note the ng-model="blah" which is saying "set $scope.blah to the selected value".

Try this:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

Here's more from AngularJS's documentation (if you haven't seen it):

for array data sources:

  • label for value in array
  • select as label for value in array
  • label group by group for value in array = select as label group by group for value in array

for object data sources:

  • label for (key , value) in object
  • select as label for (key , value) in object
  • label group by group for (key, value) in object
  • select as label group by group for (key, value) in object

For some clarification on option tag values in AngularJS:

When you use ng-options, the values of option tags written out by ng-options will always be the index of the array item the option tag relates to. This is because AngularJS actually allows you to select entire objects with select controls, and not just primitive types. For example:

app.controller('MainCtrl', function($scope) {
   $scope.items = [
     { id: 1, name: 'foo' },
     { id: 2, name: 'bar' },
     { id: 3, name: 'blah' }
   ];
});
<div ng-controller="MainCtrl">
   <select ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
   <pre>{{selectedItem | json}}</pre>
</div>

The above will allow you to select an entire object into $scope.selectedItem directly. The point is, with AngularJS, you don't need to worry about what's in your option tag. Let AngularJS handle that; you should only care about what's in your model in your scope.

Here is a plunker demonstrating the behavior above, and showing the HTML written out


Dealing with the default option:

There are a few things I've failed to mention above relating to the default option.

Selecting the first option and removing the empty option:

You can do this by adding a simple ng-init that sets the model (from ng-model) to the first element in the items your repeating in ng-options:

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.name for item in items"></select>

Note: This could get a little crazy if foo happens to be initialized properly to something "falsy". In that case, you'll want to handle the initialization of foo in your controller, most likely.

Customizing the default option:

This is a little different; here all you need to do is add an option tag as a child of your select, with an empty value attribute, then customize its inner text:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="">Nothing selected</option>
</select>

Note: In this case the "empty" option will stay there even after you select a different option. This isn't the case for the default behavior of selects under AngularJS.

A customized default option that hides after a selection is made:

If you wanted your customized default option to go away after you select a value, you can add an ng-hide attribute to your default option:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="" ng-if="foo">Select something to remove me.</option>
</select>
Tuesday, June 1, 2021
 
rob_mccann
answered 7 Months ago
12

In your example changing the data bound select to the following fixes the required directive. I'm not sure why exactly.

<select ng-model="selectedValue1" ng-options="opt for opt in ['Mazda2','Maxda3']" required>
  <option></option>
</select>
Saturday, September 18, 2021
 
jshen
answered 3 Months ago
91

It is not exactly clear what the problem is, but you can save yourself some work by binding the <select> to the currently selected currency object (so you don't have to look it up later).
select + ngOptions allow you to bind to one value while displaying another, with the following syntax:

<select ng-model="selectedCurrency"
        ng-options="currency as currency.shortDescription
                    for currency in viewModel.currencies">
</select>

In the above example, $scope.selectedCurrency will be bound to the whole currency object, but currency.shortDescription will be displayed in the dropdown.


See, also, this short demo.


UPDATE:

In case you don't need to bind to the whole currency object, but just bind updatedObject's baseCurrencyCode property to the abbreviation of the selected (in dropdown) currency, you can do it like this:

<!-- In the VIEW -->
<select ng-model="updatedObject.baseCurrencyCode"
        ng-options="c.abbreviation as c.shortDescription
                    for c in currencies">
</select>

// In the CONTROLLER
$scope.currencies = [...];
$scope.updatedObject = {
    ...
    baseCurrencyCode: <baseCurrencyCodeFromServer>
};

See, also, that short demo.

Wednesday, September 22, 2021
 
THEK
answered 3 Months ago
49

Because you are doing id as name you need to assign id to the model:

$scope.ddlRooms = $scope.options[0].id;
Wednesday, September 29, 2021
 
Vlad
answered 2 Months ago
97

I believe your problem clones a pre-existing angular issue which has a work around available.

Feel free to browse the issue and trace the conversation and some of the duplicates.

The work around suggested for Chrome/Safari/Firefox looks like this:

directive('changeOnKeyup', function changeOnKeyupDirective() {
  return function changeOnKeyupPostLink(scope, elem) {
    elem.on('keyup', elem.triggerHandler.bind(elem, 'change'));
  };
});

Edit:

The OP's issue in the comments above was closed as a duplicate for this reason.

Thursday, September 30, 2021
 
zmb
answered 2 Months ago
zmb
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share