ng-model for input type 'number' not working angularjs

31,385

Solution 1

I just ran into this same issue and managed to solve it. In my case, the model is being obtained via a RESTful $resource and the value for the amount is being provided as a string to the field, which in turn wipes out the value. In order to address this, I ended up doing the following in my controller:

$scope.cart = Cart.get(id: $routeParams.id, function(cart){
    cart.quantity = parseFloat(cart.quantity, 10);
});

which turns the value into a float, prior to updating the view. One gotcha I ran into is that my first attempt was setting $scope.cart.quantity = parseFloat($scope.cart.quantity, 10) immediately after the get. This was not working since the value was overwritten when the async call to get completed.

$scope.cart = Cart.get(id: $routeParams.id);
$scope.cart.quantity = parseFloat($scope.cart.quantity, 10); // This won't work

Hope this helps.

Solution 2

Your binded value is a string not a number.

First of all, check that your server is sending a number. If you are using PHP, you might want to use:

json_encode($array, JSON_NUMERIC_CHECK);

You might also turn your string into int or float with Javascript on the client side:

var data = ['1.9', '3']; //these won't be binded to the numbers-only input
data[0] = parseFloat(data[0]); //this will
data[1] = parseInt(data[1]);

It's not a bug as that the numbers input only accepts valid numbers (hopefully).


Note:

I also tried to bind an ng-value with an integer filter but it wont't work. Maybe because the ng-model is the one that's binded when both are found (yup, they have the same priority level).

Solution 3

I solve this problem using a custom directive:

angular.module('directives').directive('input', function() {
  return {
    restrict: 'E',
    require: 'ngModel',
    link: function(scope, $el, attrs, ngModel) {
      if ($el.get(0).type === 'number') {
        ngModel.$parsers.push(function(value) {
          return value.toString();
        });

        ngModel.$formatters.push(function(value) {
          return parseFloat(value, 10);
        });
      }
    }
  }
})

This way you do not need to change any HTTP response when the data is being obtained via a restfull resource.

Restrict this directive if necessary :)

Solution 4

value is overridden by ng-model. Remove your value property, and your ng-model will fill the input with the cart quantity.

Solution 5

I had the same problem (with an input type="range" actually) and here is my solution, using a custom directive:

app.directive('ngFloat', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, $el, attrs, ngModel) {
        ngModel.$parsers.push(function(value) {
            return parseFloat(value, 10);
        });

        ngModel.$formatters.push(function(value) {
            return value.toString();
        });
    }
  };
});

As I restricted the directive to the "ngFloat" attribute, it is need to tag the input like this:

<input ng-float type=.........

I hope this can help future visitors.

Share:
31,385
Amb
Author by

Amb

Updated on December 11, 2020

Comments

  • Amb
    Amb over 3 years

    I have integrated requirejs with angular app.. before intregrating requirejs,

    <input type="number" value="{{cart.quantity}}" ng-model="cart.quantity" />
    

    was showing the value in input box.
    But after integrating with requirejs, input box with type="number" not showing me the value.. input box with type="text" is working.

    How can I show value with type="number" ?

    Thanks

  • Amb
    Amb almost 11 years
    I didnt get "Expense.get(id: $routeParams.id, (e) -> e.amount = parseFloat(e.amount, 10) )"... can you pls elaborate ? or can you generate fiddle ?
  • Ruy Diaz
    Ruy Diaz almost 11 years
    It's coffeescript. I've updated the answer with Javascript, maybe this makes it clearer.
  • mmacneil007
    mmacneil007 almost 11 years
    I just ran into the exact same issue binding to a '$resource` response. It's unfortunate we have to parse out the number explicitly when binding but I suppose it's a small price to pay for the validation we get for free in the view. In any event, thanks a lot for posting as this quickly helped me move past this.
  • J. Bruni
    J. Bruni over 10 years
    +1 In my case, I've made the server-side provide an integer instead of a string. My model lives on the server.
  • Rob
    Rob over 10 years
    most ridiculous bug ever
  • Maxime Morin
    Maxime Morin about 10 years
    parseInt(<int>) and parseFloat(<float>) did the trick on init, thanks.
  • Admin
    Admin about 8 years
    I changed return value.toString(); to return (value || $el.attr('min')).toString();.. worked nicely +1
  • mimic
    mimic over 7 years
    Surprisingly but it worked for me. I don't understand, why. Thanks.
  • Jamie Pate
    Jamie Pate over 7 years
    I can only speculate that it is related to ngForm since the ngModelController won't be available as a property of the form without a name? not seeing anything in the code (v1.5) to confirm that though.