Angularjs currency format in input box with ng-model: how to get $formatters to fire on each input

痴心易碎 提交于 2019-12-06 20:12:13

问题


I have searched everywhere for this. Every stack overflow that has an answer, it does not actually work. Same with any examples or google group examples from for angular including the docs.

Seems simple. I want a function to get called on an input for each key pressed by the user.

simple input with a ng-model

<input class="form-control" ng-model="model.thisisnotfun" formatter type="text" required>

According to everything i read. $formatters should update the value from the model to the view calling any functions in the $formatters array. They never get called when i type in the input box.

.directive('formatter', function ($filter, $parse) {
    return {
        require: 'ngModel',

        link: function (scope, element, attrs, ngModel) {

            ngModel.$formatters.push(
                function (value) {
                    console.log('this only gets called on page load');
                }
            );
        }
    };
})

I know there are plenty of custom ways to do this, which i have already done. I do not need a work around, i just want to know how to use $formatters correctly to "format" the view data.

very very simple jsfiddle http://jsfiddle.net/fh7sB/4/

Thanks for any help.


回答1:


The $formatters get called when the model is updated in order to format the value to be presented to the user. The $parsers do the opposite, i.e. translate the value from a view string to a real model, e.g. a number.

In the forked fiddle here: http://jsfiddle.net/9tuCz/ press the button; it changes the model and fires the $formatters again.




回答2:


I could not get the $formatters function to work like i wanted. I also could not find a single example of what i was looking for anywhere so i am going to post my answer in case someone needs it.

This is a directive for formatting us currency in input boxes with ng-model

    .directive('uiCurrency', function ($filter, $parse) {
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs, ngModel) {

            function parse(viewValue, noRender) {
                if (!viewValue)
                    return viewValue;

                // strips all non digits leaving periods.
                var clean = viewValue.toString().replace(/[^0-9.]+/g, '').replace(/\.{2,}/, '.');

                // case for users entering multiple periods throughout the number
                var dotSplit = clean.split('.');
                if (dotSplit.length > 2) {
                    clean = dotSplit[0] + '.' + dotSplit[1].slice(0, 2);
                } else if (dotSplit.length == 2) {
                    clean = dotSplit[0] + '.' + dotSplit[1].slice(0, 2);
                }

                if (!noRender)
                    ngModel.$render();
                return clean;
            }

            ngModel.$parsers.unshift(parse);

            ngModel.$render = function() {
                console.log('viewValue', ngModel.$viewValue);
                console.log('modelValue', ngModel.$modelValue);
                var clean = parse(ngModel.$viewValue, true);
                if (!clean)
                    return;

                var currencyValue,
                    dotSplit = clean.split('.');

                // todo: refactor, this is ugly
                if (clean[clean.length-1] === '.') {
                     currencyValue = '$' + $filter('number')(parseFloat(clean)) + '.';

                } else if (clean.indexOf('.') != -1 && dotSplit[dotSplit.length - 1].length == 1) {
                    currencyValue = '$' + $filter('number')(parseFloat(clean), 1);
                } else if (clean.indexOf('.') != -1 && dotSplit[dotSplit.length - 1].length == 1) {
                    currencyValue = '$' + $filter('number')(parseFloat(clean), 2);
                } else {
                     currencyValue = '$' + $filter('number')(parseFloat(clean));
                }

                element.val(currencyValue);
            };

        }
    };
})



回答3:


Make sure you're actually returning a valid value from your functions.

What's likely happening is since the parser returns the same value each time, the formatter assumes the formatted output will not have changed either so it skips the call.



来源:https://stackoverflow.com/questions/18940865/angularjs-currency-format-in-input-box-with-ng-model-how-to-get-formatters-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!