The problem I had was that the select
had a blank option
at the top even though the model had a value corresponding to the value of the first option.
JavaScript:
var MyApp, Day;
Day = (function() {
function Day() {}
Day.MON = 'Mon';
Day.TUE = 'Tue';
Day.WED = 'Wed';
return Day;
})();
MyApp = angular.module('MyApp1', []);
MyApp.controller('MyController', function($scope) {
$scope.myDay = Day.MON;
$scope.Day = Day;
});
HTML:
<div ng-app="MyApp1">
<div ng-controller="MyController">
Current value: {{myDay}}
<select ng-model="myDay">
<option ng-value="Day.MON">
{{Day.MON}}
</option>
<option ng-value="Day.TUE">
{{Day.TUE}}
</option>
<option ng-value="Day.WED">
{{Day.WED}}
</option>
</select>
</div>
</div>
Output HTML:
...
Current value: Mon
<select class="ng-pristine ng-valid" ng-model="myDay"><option value="? string:Mon ?"></option>
<option class="ng-binding" value="Mon" ng-value="Day.MON">
Mon
</option>
<option class="ng-binding" value="Tue" ng-value="Day.TUE">
Tue
</option>
<option class="ng-binding" value="Wed" ng-value="Day.WED">
Wed
</option>
</select>
...
Note that the model has the correct value and that there is a blank option
added directly inside the select
element.
Demo: http://jsfiddle.net/ndLtLmrv/
There are many similar questions on StackOverflow but most of them seems to be caused by an uninitialised model.
After some hours of searching for an answer and debugging (since my actual code is a lot larger I tried many different things) I finally found the solution! It was really simple actually. All I had to do was to remove all the whitespace inside the option
elements.
New HTML:
...
<select ng-model="myDay">
<option ng-value="Day.MON">{{Day.MON}}</option>
<option ng-value="Day.TUE">{{Day.TUE}}</option>
<option ng-value="Day.WED">{{Day.WED}}</option>
</select>
...
This will give the expected output.
The reason why I didn't write like this from the beginning was that I was using HAML, which added the new line and indentation automatically. I solved this by adding a <
to the %option
(see HAML whitespace removal).
I still don't see why this happened though as I have similar select
s which work just fine even though they have whitespace inside the option
. Now I've got a solution at least.
EDIT:
Now I think I know why the problem occured. It seems that angular compares the value in ng-model
with the option value
s before ng-value
is evaluated. Since the options didn't have any value
s, the model was compared to the content of the options instead. This explains why it didn't work in the first case (there's too much whitespace) while it worked when I removed the whitespace.
Thus, the solution I proposed here only works if the content of the option
is the same as its value
. By manually adding a value
the problem is solved.
This should be a more correct solution to the initial problem:
...
<select ng-model="myDay">
<option ng-value="Day.MON" value="{{Day.MON}}">
Mon
</option>
<option ng-value="Day.TUE" value="{{Day.TUE}}">
Tue
</option>
<option ng-value="Day.WED" value="{{Day.WED}}">
Wed
</option>
</select>
...