AngularJS: вовремя, чтобы показать "$ 50,000.00", когда не сфокусировался, но показывал "50000", когда фокусировался?

У меня есть ввод для отображения отформатированного числа. Обычно, когда он не имеет фокуса, он должен показывать строку с формами, например. '$ 50,000.00. Но когда он имеет фокус, он должен показывать необработанное значение, например. 50000 для редактирования.

Есть ли встроенные функции? Благодарю!

Ответ 1

Вот директива (formatOnBlur), которая делает то, что вы хотите.
Обратите внимание, что форматируется только отображаемое значение элемента (значение модели всегда будет неформатировано).

Идея заключается в том, что вы регистрируете слушателей для событий focus и blur и обновляете отображаемое значение на основе состояния фокусировки элемента.

app.directive('formatOnBlur', function ($filter, $window) {
    var toCurrency = $filter('currency');

    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            var rawElem = elem[0];
            if (!ctrl || !rawElem.hasOwnProperty('value')) return;

            elem.on('focus', updateView.bind(null, true));
            elem.on('blur',  updateView.bind(null, false));

            function updateView(hasFocus) {
                if (!ctrl.$modelValue) { return; }
                var displayValue = hasFocus ?
                        ctrl.$modelValue :
                        toCurrency(ctrl.$modelValue);
                rawElem.value = displayValue;
            }
            updateView(rawElem === $window.document.activeElement);
        }
    };
});

См. также эту короткую демонстрацию.

Ответ 2

Вы ищете ngModel. $parsers и ngModel. $formatters.

Я собрал простую демонстрацию:

http://jsfiddle.net/BuriB/nD2tk/

  angular.module('app', [])
      .controller('TestCntrl', function TestCntrl ($scope) {
        $scope.value = 50000;
      })
      .directive('numberFormatter', ['$filter', function ($filter) {
        var decimalCases = 2,
            whatToSet = function (str) {
              /**
               * TODO:
               * don't allow any non digits character, except decimal seperator character
               */
              return str ? Number(str) : '';
            },
            whatToShow = function (num) {
              return '$' + $filter('number')(num, decimalCases);
            };

        return {
          restrict: 'A',
          require: 'ngModel',
          link: function (scope, element, attr, ngModel) {
            ngModel.$parsers.push(whatToSet);
            ngModel.$formatters.push(whatToShow);

            element.bind('blur', function() {
              element.val(whatToShow(ngModel.$modelValue))
            });
            element.bind('focus', function () {
              element.val(ngModel.$modelValue);
            });
          }
        };
      }]);

См. также этот Рабочая демонстрация @Eric Hannum.

Ответ 3

вы можете использовать ng-focus для применения фильтра/преобразования вашей модели, чтобы сделать его необработанным значением и ng-blur, чтобы сделать его форматированным значением, как для части форматирования. Боюсь, вам придется создавать собственный фильтр, я не знаю ни одного существующего для выполнения этой операции, хотя, возможно, есть.

Ответ 4

myApp.directive('myField',function($filter){
  return {
            restrict: 'E',
            require: '?ngModel',
            scope : true,
            template: '<input type="text" ng-focus="clearFormat()" ng-blur="formatField()"/>',
            link : function (scope, element, attrs,ctrl){
                var field = element.find('input');
                ctrl.$render = function() {
                    field.val($filter('currency')(ctrl.$viewValue));
                };
                scope.clearFormat = function(){
                   field.val(ctrl.$viewValue);
                }
                scope.formatField = function(){
                   field.val($filter('currency')(ctrl.$viewValue));
                }
                function updateViewValue() {
                    scope.$apply(function() {
                        ctrl.$setViewValue(field.val());
                    });
                }

                field.on('change', updateViewValue);
            }
        };
})

В html

 <my-field ng-model="amount"></my-field>

Это будет работать, только если вы используете angular 1.2 или выше. Кроме того, вам нужно реализовать ng-focus и ng-blur с помощью собственных

Ответ 5

  angular.module('app', [])
        .controller('TestCntrl', function TestCntrl($scope) {
            $scope.value = 50000.23;
        })
        .directive('numberFormatter', ['$filter', function ($filter) {
            return {
                restrict: 'A',
                require: 'ngModel',
                scope: { 'decimal': '=decimal' },
                link: function (scope, element, attr, ngModel) {
                    ngModel.$parsers.push(whatToSet);
                    ngModel.$formatters.push(whatToShow);
                    element.bind('blur', function () {
                        element.val(whatToShow(ngModel.$modelValue, scope.decimal))
                    });
                    element.bind('focus', function () {
                        element.val(ngModel.$modelValue);
                    });
                    function whatToSet(str) {
                        var num = 0
                        var numbe = num !== undefined ? num : 0;
                        var strr = str.toString();
                        strr = strr.replace(',', '.');
                        numbe = parseFloat(strr);
                        return numbe;
                    }
                    function whatToShow(num) {
                        if (num) {
                            return '$' + $filter('number')(num, scope.decimal);
                        } else {
                            return '';
                        }
                    };
                }
            };
        }]);
<!doctype html>
<html lang="en">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
</head>
<body ng-app="app" ng-controller="TestCntrl">
    <input type="text" id="exampleInput" name="input" ng-model="value" number-formatter decimal="'0'" /><br />
    <strong>value in the model:</strong> {{value}}
</body>
</html>