Question

Update: question is obsolete for latest Angular version, see tsh's comment on this post


I have bound a checkbox to a value:

<input type="checkbox" ng-model="checkbox" ng-true-value="1" ng-false-value="0" />

The value of the checkbox is set to 1 in the controller:

function Controller($scope) {
    $scope.checkbox = 1
}

However, initially the checkbox does not appear checked. If I change the initial value of $scope.checkbox to "1", it does. (jsfiddle demo)

I have tried all kinds of variations:

ng-true-value="{{1}}"
ng-true-value="{{Number(1)}}"
ng-true-value="{{parseInt('1')}}"

None of them work. How can I make angular treat the arguments as a number?

Was it helpful?

Solution

You can use ngChecked, If the expression is truthy, then special attribute "checked" will be set on the element

<input type="checkbox" 
    ng-model="checkbox" 
    ng-true-value="1" 
    ng-false-value="0" 
    ng-checked="checkbox == 1" />

And you can use $scope.$watch to convert it to number

$scope.$watch(function(){
    return $scope.checkbox;
}, function(){
    $scope.checkbox = Number($scope.checkbox);
    console.log($scope.checkbox, typeof $scope.checkbox);
},true);

DEMO

OTHER TIPS

I have created directive for that, seems to work fine:

angular.module('app').directive('cdTrueValue', [function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      ngModel.$parsers.push(function(v){
        return v ? scope.$eval(attrs.cdTrueValue) : scope.$eval(attrs.cdFalseValue);
      });

      ngModel.$formatters.push(function(value) {
          return value === scope.$eval(attrs.cdTrueValue);
      });
    }
  };
}]);

Usage:

<input type="checkbox" ng-model="checkbox" cd-true-value="1" cd-false-value="0" />

DEMO

HTML attributes do not have any types. They can not contain anything else, then a string, so it is always a string. End of story.

You can not differentiate between between 1 and "1" in an HTML attribute. Angular tries to keep up with that, so only strings will work.

The first approach above is great. That's works fine. You can also use ng-change directive if you need use dynamic model (e.g. linked with ID or number - in case you wanna work with ID you don't know ahead). Just pass model as parameter: ng-change="fooBar(model[ID])" , catch in controller function and use Number(model[ID]) re-type. That's convert true as 1, false as 0 and you can work with this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top