I have a <select>
element that uses ng-options
to generate the select list and hopefully set the selected to the value of the ng-model
. Here is my html:
<td style="text-align:center">
<ng-form name="IsTobaccoForm">
<select name="Input" required ng-model="dep.IsTobacco" ng-options="item.value as item.text for item in yesNoList"></select>{{dep.IsTobacco}}
<span class="alert-error" ng-show="IsTobaccoForm.Input.$error.required"><strong>*Required</strong></span>
</ng-form>
</td>
My controller contains the following code:
$scope.yesNoList = [{ value: true, text: 'Y' }, { value: false, text: 'N'}];
If the IsTobacco
value of the item is true, the value is set properly and everything is fine. However, if it is false, the required error appears, even though {{dep.IsTobacco}}
renders as false. The really weird part is that if I change the selected item in the list to true, it works fine, however if I set it to false, a new blank item is added to the list and that blank item is selected.
If it seems like the issues do not lie in the lines posted above, I could gladly post more code.
Thanks!
EDIT: I also used chrome debugger and saw that when the data was being initiated in Angular, the value of IsTobacco
was equal to false
.
Edit 2: If anyone viewing this is new to AngularJS, I would definitely recommend reading these 2 articles: part 1 & part 2. They are an overview of AngularJS forms.
The reason this happens is because a value of false
gets interpreted as a lack of ngModel
when used with required
. As discussed here, consider this excerpt from the Angular source:
var validator = function(value) {
if (attr.required && (isEmpty(value) || value === false)) {
ctrl.$setValidity('required', false);
If there is a required attribute and its value is false
, it does not pass validation. This is probably intentional for the sake of more easily validating required checkboxes, in which case the default value for unchecked is false
.
It may not need to be this way, considering that checkboxes can take ng-true-value
and ng-false-value
attributes but I guess it was either do this or enforce the use of non-true
and non-false
values for those attributes on every checkbox, and this was the better choice.
One workaround would be to use the strings 'true' and 'false' instead.