322

I have searched Google and can't find anything on this.

I have this code.

<select ng-model="somethingHere" 
        ng-options="option.value as option.name for option in options"
></select>

With some data like this

options = [{
   name: 'Something Cool',
   value: 'something-cool-value'
}, {
   name: 'Something Else',
   value: 'something-else-value'
}];

And the output is something like this.

<select ng-model="somethingHere"  
        ng-options="option.value as option.name for option in options" 
        class="ng-pristine ng-valid">

    <option value="?" selected="selected"></option>
    <option value="0">Something Cool</option>
    <option value="1">Something Else</option>
</select>

How is it possible to set the first option in the data as the default value so you would get a result like this.

<select ng-model="somethingHere" ....>
    <option value="0" selected="selected">Something Cool</option>
    <option value="1">Something Else</option>
</select>
IAbstract
  • 19,551
  • 15
  • 98
  • 146
iConnor
  • 19,997
  • 14
  • 62
  • 97
  • 3
    It would be nice if there was an answer that didn't assume that angular was being used to build the options. What if the options are already part of the markup? – pspahn Apr 09 '15 at 18:57
  • 1
    @pspahn - according to https://docs.angularjs.org/api/ng/directive/ngOptions: only `a **single** hard-coded – The DIMM Reaper Aug 19 '15 at 17:31
  • 1
    @pspahn that would not answer the OP, but a quite different question... – Mario Trucco Aug 11 '16 at 08:30

23 Answers23

379

You can simply use ng-init like this

<select ng-init="somethingHere = options[0]" 
        ng-model="somethingHere" 
        ng-options="option.name for option in options">
</select>
zs2020
  • 53,766
  • 29
  • 154
  • 219
  • 21
    I had a problem with this working, it was that I was using 'track by', removing it fixed the problem, just in case that helps someone down the line :D – DrCord Apr 15 '14 at 23:21
  • 61
    Nothing wrong with this answer, but ng-init failed for me in my specific case. Problem was that the value I was using was not available yet at the time ng-init ran: I got the value via an ajax call and at that moment the ng-init was already finished. In the end I used a watcher on that value and in that function I did the same as I did in ng-init. That worked. – maurits Sep 05 '14 at 14:02
  • 2
    I too had issues getting this worked out, @maurits comment led me to this [stackoverflow.com/questions/22348886](https://stackoverflow.com/questions/22348886/angularjs-ng-options-not-binding-after-ajax-call/22350382#22350382) Enjoy! – Michael Dec 05 '14 at 16:19
  • 5
    The documentation of Angular says to better use the controller $scope for initializing these kind of values https://docs.angularjs.org/api/ng/directive/ngInit – Fortuna Mar 17 '15 at 14:01
  • 3
    warning: using ng-init for this purpose can lead to excessive calls to the $digest() method, which can cause your console output to look all red and ugly with messages lik "10 $digest() iterations reached. Aborting!" – DMac the Destroyer Apr 27 '15 at 22:27
  • the simplest solution for me was to just put in between the enclosing ) – Mariusz Aug 12 '15 at 19:04
  • This worked great for me have to remember to remove track by option in the ng-options attribute then in the ng-init you simply set your "selected value" i.e. the ng-model to the whatever array item value of your collection e.g. options[0] being the first options value. – Trevor Jun 17 '16 at 15:35
  • 1
    I've tried this without any luck. I have ng-options set to `names for names in namesFilter('zoneManagers')`, a function that reorganizes names in an object. I've my ng-model to the first item by trying `$scope.zoneName = $scope.namesFilter('zoneManagers')[0]` without any luck. – Coded Container Jul 26 '16 at 19:20
  • @Mariusz is right, you just need to make sure that the option value is set to an empty string. – Coded Container Jul 26 '16 at 19:30
241

If you want to make sure your $scope.somethingHere value doesn't get overwritten when your view initializes, you'll want to coalesce (somethingHere = somethingHere || options[0].value) the value in your ng-init like so:

<select ng-model="somethingHere" 
        ng-init="somethingHere = somethingHere || options[0].value"
        ng-options="option.value as option.name for option in options">
</select>
Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • 22
    This solution worked well and is a better one than the selected answer. – Michael Allan Jackson Mar 07 '14 at 15:16
  • shouldn't the ng-init look like this ng-init="somethingHere = somethingHere || options[0]" ?? – infinitloop Jul 25 '14 at 15:07
  • 1
    How to deal with `options` being empty? Like in case of `options` data is coming from external source. – null May 04 '15 at 21:11
  • 1
    @suud you'd just need to check options && options.length > 0 in your ng-init. Really, most of this should be done in your controller, so it's testable. – Ben Lesh May 05 '15 at 17:11
  • @BenLesh If i want to write some text(string) instead of first option.`ng-init="somethingHere= somethingHere || 'Select one' " ` i tried like this. but it didn't work. what is wrong in my code – codelearner Mar 28 '16 at 07:01
72

Try this:

HTML

<select 
    ng-model="selectedOption" 
    ng-options="option.name for option in options">
</select>

Javascript

function Ctrl($scope) {
    $scope.options = [
        {
          name: 'Something Cool',
          value: 'something-cool-value'
        }, 
        {
          name: 'Something Else',
          value: 'something-else-value'
        }
    ];

    $scope.selectedOption = $scope.options[0];
}

Plunker here.

If you really want to set the value that will be bound to the model, then change the ng-options attribute to

ng-options="option.value as option.name for option in options"

and the Javascript to

...
$scope.selectedOption = $scope.options[0].value;

Another Plunker here considering the above.

Michael Benford
  • 14,044
  • 3
  • 60
  • 60
  • 2
    The problem is I would have to do this for loads of select boxes. – iConnor Aug 12 '13 at 19:07
  • Didn't get it. What would you have to do? – Michael Benford Aug 12 '13 at 19:15
  • I would have to do it manually for maybe **50+** select boxes – iConnor Aug 12 '13 at 19:20
  • You mean setting the default value for every select box? If so I guess that's not clear in your question. Anyway, am I right to assume that you'd have to load the items into every select box? If so I don't think initializing their default values would be a big deal. – Michael Benford Aug 12 '13 at 19:46
  • 1
    My problem is that the index of the option is returned from a "submit" on the form. What I need is what you are calling option.name, which is what was returned from a plain old rails form. The checkbox and radio buttons work fine since you use ng-repeat to get the correct markup. How do I get the option.name returned at form submission time? – pferrel Jan 04 '14 at 00:53
  • often we want to use the loaded "selectedOption" as selected option and its not correct that set first option to it. because we lost the loaded "selectedOption". (excuse me, I'm weak in English!) – Omid.Hanjani Jan 14 '15 at 07:03
  • @OmidRH The OP explicitly asked how to set the first item in his/her dataset as the default value of the `select` element. None was said about preserving existing values. – Michael Benford Jan 14 '15 at 18:15
  • Why can't you just add a string value to $scope.selectedOption instead of setting this to a previous object property? – Coded Container Jan 23 '17 at 20:41
  • Thanks @MichaelBenford that's the only answer led me down the right path. – Darragh Enright Nov 30 '21 at 16:54
42

Only one answer by Srivathsa Harish Venkataramana mentioned track by which is indeed a solution for this!

Here is an example along with Plunker (link below) of how to use track by in select ng-options:

<select ng-model="selectedCity"
        ng-options="city as city.name for city in cities track by city.id">
  <option value="">-- Select City --</option>
</select>

If selectedCity is defined on angular scope, and it has id property with the same value as any id of any city on the cities list, it'll be auto selected on load.

Here is Plunker for this: http://plnkr.co/edit/1EVs7R20pCffewrG0EmI?p=preview

See source documentation for more details: https://code.angularjs.org/1.3.15/docs/api/ng/directive/select

Community
  • 1
  • 1
mikhail-t
  • 4,103
  • 7
  • 36
  • 56
33

I think, after the inclusion of 'track by', you can use it in ng-options to get what you wanted, like the following

 <select ng-model="somethingHere" ng-options="option.name for option in options track by option.value" ></select>

This way of doing it is better because when you want to replace the list of strings with list of objects you will just change this to

 <select ng-model="somethingHere" ng-options="object.name for option in options track by object.id" ></select>

where somethingHere is an object with the properties name and id, of course. Please note, 'as' is not used in this way of expressing the ng-options, because it will only set the value and you will not be able to change it when you are using track by

  • This is what worked for me. I think angular needed something to identify the object in my scope's model as equivalent to a choice the reference list. "track by guarantor.code" did the trick! – markbaldy Jun 09 '14 at 11:00
23

The accepted answer use ng-init, but document says to avoid ng-init if possible.

The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.

You also can use ng-repeat instead of ng-options for your options. With ng-repeat, you can use ng-selected with ng-repeat special properties. i.e. $index, $odd, $even to make this work without any coding.

$first is one of the ng-repeat special properties.

  <select ng-model="foo">
    <option ng-selected="$first" ng-repeat="(id,value) in myOptions" value="{{id}}">
      {{value}}
    </option>
  </select>

---------------------- EDIT ----------------
Although this works, I would prefer @mik-t's answer when you know what value to select, https://stackoverflow.com/a/29564802/454252, which uses track-by and ng-options without using ng-init or ng-repeat.

This answer should only be used when you must select the first item without knowing what value to choose. e.g., I am using this for auto completion which requires to choose the FIRST item all the time.

allenhwkim
  • 27,270
  • 18
  • 89
  • 122
  • 5
    This works but shouldn't be used as `ng-options` is faster and more optimized than `ng-repeat`. – Iso Jun 17 '15 at 08:00
  • @Iso not disagreeing with you, but do you have a source for that information? – Adam Plocher Aug 21 '17 at 13:41
  • 1
    Right here in the docs: https://docs.angularjs.org/api/ng/directive/ngOptions “more flexibility in how the ` – Iso Aug 22 '17 at 08:39
16

My solution to this was use html to hardcode my default option. Like so:

In HAML:

%select{'ng-model' => 'province', 'ng-options' => "province as province for province in summary.provinces", 'chosen' => "chosen-select", 'data-placeholder' => "BC & ON"}
  %option{:value => "", :selected => "selected"}
    BC &amp; ON

In HTML:

<select ng-model="province" ng-options="province as province for province in summary.provinces" chosen="chosen-select" data-placeholder="BC & ON">
  <option value="" selected="selected">BC &amp; ON</option>
</select>

I want my default option to return all values from my api, that's why I have a blank value. Also excuse my haml. I know this isn't directly an answer to the OP's question, but people find this on Google. Hope this helps someone else.

penner
  • 2,707
  • 1
  • 37
  • 48
  • 1
    I've tried to convert this to **html** but it has failed in all online converters that I've tried. – iConnor May 13 '14 at 18:09
  • 5
    Why not post html? I mean, was posting the code like that really necessary? It's not like the OP was using a templating engine in the question. – arg20 Jun 20 '14 at 01:03
15

Use below code to populate selected option from your model.

<select id="roomForListing" ng-model="selectedRoom.roomName" >

<option ng-repeat="room in roomList" title="{{room.roomName}}" ng-selected="{{room.roomName == selectedRoom.roomName}}" value="{{room.roomName}}">{{room.roomName}}</option>

</select>
eebbesen
  • 5,070
  • 8
  • 48
  • 70
  • Worked lekker for me. The asynchronous call responsible for binding options for my select list was a little slower than the one that brought ng-model so this approached helped me a lot. Thanks Eebbesen:-) – ajaysinghdav10d May 11 '16 at 16:11
  • This works for me as well. Simple and understandable. – Kent Aguilar Aug 08 '16 at 18:00
10

Depending on how many options you have, you could put your values in an array and auto-populate your options like this

<select ng-model="somethingHere.values" ng-options="values for values in [5,4,3,2,1]">
   <option value="">Pick a Number</option>
</select>
Alex Hawkins
  • 616
  • 7
  • 10
10

In my case, I was need to insert a initial value only to tell to user to select an option, so, I do like the code below:

<select ...
    <option value="" ng-selected="selected">Select one option</option>
</select>

When I tryed an option with the value != of an empty string (null) the option was substituted by angular, but, when put an option like that (with null value), the select apear with this option.

Sorry by my bad english and I hope that I help in something with this.

9

Using select with ngOptions and setting a default value:

See the ngOptions documentation for more ngOptions usage examples.

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: '2', name: 'Option B'} //This sets the default value of the select in the ui
    };
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
  <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>

plnkr.co

Official documentation about HTML SELECT element with angular data-binding.

Binding select to a non-string value via ngModel parsing / formatting:

(function(angular) {
  'use strict';
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;
        });
      }
    };
  });
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.1/angular.min.js"></script>
<body ng-app="nonStringSelect">
  <select ng-model="model.id" convert-to-number>
  <option value="1">One</option>
  <option value="2">Two</option>
  <option value="3">Three</option>
</select>
{{ model }}
</body>

plnkr.co

Other example:

angular.module('defaultValueSelect', [])
 .controller('ExampleController', ['$scope', function($scope) {
   $scope.availableOptions = [
     { name: 'Apple', value: 'apple' }, 
     { name: 'Banana', value: 'banana' }, 
     { name: 'Kiwi', value: 'kiwi' }
   ];
   $scope.data = {selectedOption : $scope.availableOptions[1].value};
}]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<body ng-app="defaultValueSelect">
  <div ng-controller="ExampleController">
  <form name="myForm">
    <select ng-model="data.selectedOption" required ng-options="option.value as option.name for option in availableOptions"></select>
  </form>  
  </div>
</body>

jsfiddle

shilovk
  • 11,718
  • 17
  • 75
  • 74
5

This worked for me.

<select ng-model="somethingHere" ng-init="somethingHere='Cool'">
    <option value="Cool">Something Cool</option>
    <option value="Else">Something Else</option>
</select>
Bishan
  • 15,211
  • 52
  • 164
  • 258
4

In response to Ben Lesh's answer, there should be this line

ng-init="somethingHere = somethingHere || options[0]" 

instead of

ng-init="somethingHere = somethingHere || options[0].value" 

That is,

<select ng-model="somethingHere"
        ng-init="somethingHere = somethingHere || options[0]"
        ng-options="option.name for option in options track by option.value">
</select>
Community
  • 1
  • 1
3

In my case since the default varies from case to case in the form. I add a custom attribute in the select tag.

 <select setSeletected="{{data.value}}">
      <option value="value1"> value1....
      <option value="value2"> value2....
       ......

in the directives I created a script that checks the value and when angular fills it in sets the option with that value to selected.

 .directive('setSelected', function(){
    restrict: 'A',
    link: (scope, element, attrs){
     function setSel=(){
     //test if the value is defined if not try again if so run the command
       if (typeof attrs.setSelected=='undefined'){             
         window.setTimeout( function(){setSel()},300) 
       }else{
         element.find('[value="'+attrs.setSelected+'"]').prop('selected',true);          
       }
     }
    }

  setSel()

})

just translated this from coffescript on the fly at least the jist of it is correct if not the hole thing.

It's not the simplest way but get it done when the value varies

Bruno
  • 401
  • 5
  • 13
3

Simply use ng-selected="true" as follows:

<select ng-model="myModel">
        <option value="a" ng-selected="true">A</option>
        <option value="b">B</option>
</select>
Bishan
  • 15,211
  • 52
  • 164
  • 258
Shevon Silva
  • 139
  • 1
  • 3
3

This working for me

ng-selected="true" 
I don't know
  • 701
  • 2
  • 8
  • 15
2

I would set the model in the controller. Then the select will default to that value. Ex: html:

<select ng-options="..." ng-model="selectedItem">

Angular controller (using resource):

myResource.items(function(items){
  $scope.items=items;
  if(items.length>0){
     $scope.selectedItem= items[0];
//if you want the first. Could be from config whatever
  }
});
Jens Alenius
  • 1,931
  • 2
  • 16
  • 20
1

If you are using ng-options to render you drop down than option having same value as of ng-modal is default selected. Consider the example:

<select ng-options="list.key as list.name for list in lists track by list.id" ng-model="selectedItem">

So option having same value of list.key and selectedItem, is default selected.

Rubi saini
  • 2,515
  • 23
  • 21
1

I needed the default “Please Select” to be unselectable. I also needed to be able to conditionally set a default selected option.

I achieved this the following simplistic way: JS code: // Flip these 2 to test selected default or no default with default “Please Select” text //$scope.defaultOption = 0; $scope.defaultOption = { key: '3', value: 'Option 3' };

$scope.options = [
   { key: '1', value: 'Option 1' },
   { key: '2', value: 'Option 2' },
   { key: '3', value: 'Option 3' },
   { key: '4', value: 'Option 4' }
];

getOptions();

function getOptions(){
    if ($scope.defaultOption != 0)
    { $scope.options.selectedOption = $scope.defaultOption; }
}

HTML:

<select name="OptionSelect" id="OptionSelect" ng-model="options.selectedOption" ng-options="item.value for item in options track by item.key">
<option value="" disabled selected style="display: none;"> -- Please Select -- </option>
</select>
<h1>You selected: {{options.selectedOption.key}}</h1>         

I hope this helps someone else that has similar requirements.

The "Please Select" was accomplished through Joffrey Outtier's answer here.

Community
  • 1
  • 1
Spencer Sullivan
  • 527
  • 6
  • 13
0

If you have some thing instead of just init the date part, you can use ng-init() by declare it in your controller, and use it in the top of your HTML. This function will work like a constructor for your controller, and you can initiate your variables there.

angular.module('myApp', [])
 .controller('myController', ['$scope', ($scope) => {
   $scope.allOptions = [
     { name: 'Apple', value: 'apple' }, 
     { name: 'Banana', value: 'banana' }
   ];
   $scope.myInit = () => {
      $scope.userSelected = 'apple'
      // Other initiations can goes here..
   }
}]);


<body ng-app="myApp">
  <div ng-controller="myController" ng-init="init()">
    <select ng-model="userSelected" ng-options="option.value as option.name for option in allOptions"></select>
   </div>
</body>
ofir_aghai
  • 3,017
  • 1
  • 37
  • 43
0
    <!--
    Using following solution you can set initial 
default value at controller as well as after change option selected value shown as default.
    -->
    <script type="text/javascript">
      function myCtrl($scope)
        {
          //...
            $scope.myModel=Initial Default Value; //set default value as required
          //..
        }
    </script>
    <select ng-model="myModel" 
                ng-init="myModel= myModel"
                ng-options="option.value as option.name for option in options">
        </select>
Mohammad Rahman
  • 239
  • 3
  • 7
0

try this in your angular controller...

$somethingHere = {name: 'Something Cool'};

You can set a value, but you are using a complex type and the angular will search key/value to set in your view.

And, if does not work, try this : ng-options="option.value as option.name for option in options track by option.name"

Wesley Rocha
  • 311
  • 2
  • 4
-2

I think the easiest way is

 ng-selected="$first"
Cesar Alonso
  • 477
  • 5
  • 11