jenryb jenryb - 4 months ago 48
AngularJS Question

Angular filter for currency to allow typing negative numbers

I have a directive that filters currency by adding a decimal point as the user types.

My problem is that it will not allow negatives. It would be nice to allow a user to type a '-' sign and have it always appear at the beginning of the number, or type a '+' and have it disappear.

Needs:


  1. Format decimal field as user types

  2. Field must be a number

  3. Must allow negatives
    -

  4. Allow 0.00 as a number input



Check out my Plunker here . It has
input = number
but does not allow negative numbers:

app.directive('format', ['$filter', function ($filter) {
return {
require: 'ngModel', //there must be ng-model in the html
link: function (scope, elem, attr, ctrl) {
if (!ctrl) return;

ctrl.$parsers.unshift(function (viewValue, modelValue) {
var plainNumber = viewValue.replace(/[^-+0-9]/g,'');

// use angular internal 'number' filter
plainNumber = $filter('number')(plainNumber / 100, 2).replace(/,/g, '');

// update the $viewValue
ctrl.$setViewValue(plainNumber);

// reflect on the DOM element
ctrl.$render();

// return the modified value to next parser
return plainNumber;
});
}
};
}]);

Answer

This will do exactly what you want it to do:

var app = angular.module('App',[]);

 app.controller('MainCtrl', function ($scope) {


});

 app.directive('format', ['$filter', function ($filter) {
 return {
            require: 'ngModel', //there must be ng-model in the html
            link: function (scope, elem, attr, ctrl) {
                if (!ctrl) return;

                ctrl.$parsers.unshift(function (viewValue, modelValue) {
                    var plainNumber = viewValue.replace(/[^-+0-9]/g,'');
                    var newVal = plainNumber.charAt(plainNumber.length-1);
                    var positive = plainNumber.charAt(0) != '-';
                    if(isNaN(plainNumber.charAt(plainNumber.length-1))){
                      plainNumber = plainNumber.substr(0,plainNumber.length-1)
                    }
                    //use angular internal 'number' filter
                    plainNumber = $filter('number')(plainNumber / 100, 2).replace(/,/g, '');
                    if(positive && newVal == '-'){
                      plainNumber = '-' + plainNumber;
                    }
                    else if(!positive && newVal == '+'){
                      plainNumber = plainNumber.substr(1);
                    }
                    plainNumber.replace('.', ',');
                    //update the $viewValue
                    ctrl.$setViewValue(plainNumber);
                    //reflect on the DOM element
                    ctrl.$render();
                    //return the modified value to next parser
                    return plainNumber;
                });
            }
        };

}]);

Just remove the type="number" from:

<input ng-model="amount" format="number" />
Comments