Angular,输入字段,带有货币掩码指令,用于货币格式

时间:2013-10-24 20:40:29

标签: angularjs angularjs-directive

我正在尝试使用http://jquerypriceformat.com/

为欧盟货币字段创建输入掩码

到目前为止,在我的指令中,输入正确显示给应用了掩码的用户,但我认为有些错误,因为POST值是以奇怪的格式发送的,与我们在输入字段中看到的完全不同。

我包含priceformat.js

<script src="js/jquery.price_format.1.8.min.js"></script>

<input type="text" currency-input ng-model...>

并且有角度:

app.directive('currencyInput', function() {
    return {
      require: '?ngModel',
      link: function($scope, element, attrs, controller) {
        element.priceFormat({
            prefix: '',
            centsSeparator: ',',
            thousandsSeparator: '.'
        });
      }
    };
});

我的输入正确显示了掩码的值,但是在POST数据(由angular调用)时,它是一个不同的值,我缺少什么?

输入&gt; 2.200,80 |发布&gt; 22,0080

由于

5 个答案:

答案 0 :(得分:31)

从你的例子中我看不到链接返回了什么。

我会写一些指令:

.directive('format', ['$filter', function ($filter) {
    return {
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;


            ctrl.$formatters.unshift(function (a) {
                return $filter(attrs.format)(ctrl.$modelValue)
            });


            ctrl.$parsers.unshift(function (viewValue) {

          elem.priceFormat({
            prefix: '',
            centsSeparator: ',',
            thousandsSeparator: '.'
        });                

                return elem[0].value;
            });
        }
    };
}]);

演示1 Fiddle

enter image description here

如果您想启动过滤器,请使用$formatters

现在link是:

link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            var format = {
                    prefix: '',
                    centsSeparator: ',',
                    thousandsSeparator: ''
                };

            ctrl.$parsers.unshift(function (value) {
                elem.priceFormat(format);

                return elem[0].value;
            });

            ctrl.$formatters.unshift(function (value) {
                elem[0].value = ctrl.$modelValue * 100 ;
                elem.priceFormat(format);
                return elem[0].value;
            })
        }

演示2 Fiddle

答案 1 :(得分:17)

$parser推送到控制器,仅在使用$setViewValue()$render()与输入不匹配时更新该值。

app.directive('currencyInput', function() {
    return {
      require: '?ngModel',
      link: function($scope, element, attrs, controller) {
        return ctrl.$parsers.push(function(inputValue) {

            ...

            if (result != inputValue) {
                controller.$setViewValue(res);
                controller.$render();
            }
        });
      }
    };
});

这是我用于货币输入指令的逻辑的小提琴:Fiddle

答案 2 :(得分:3)

晚会,但我相信这值得另一个答案!我一直在使用ng-currency模块。这真是太棒了。

答案 3 :(得分:1)

我喜欢Dubilla的简洁和优雅的方法。我决定在其上添加一些功能(并给予应有的信誉),使其非常接近现实世界的用例。

我在github项目中使用它来创建一些有用的财务指令github

值得注意的额外功能:

  1. 它会对输入进行严格检查以提供有效的响应。
  2. 它有一些键盘快捷键,可以更快地输入大数字。
  3. 我将展示如何将其与bootstrap和ngmodel css更新集成。
  4. 作为奖励,我将表单的ngmonel作为JSON输出,以帮助人们了解表单验证的实时工作方式
  5. 它还使用POJO作为ngmodel:

    function Money() {
        this.notional = 0;
        this.maxValue = 99999999999.9;
        this.maxValueString = "99,999,999,999.9";
        this.maxPrecision = 10;
    }
    

    你可以像Bootstrap 3一样使用它:

    <h1>Currency Formatting directive</h1>
    
    <div class="row">
    
        <div class="col-md-6">
            <form name="myForm">
    
                <div class="form-group" ng-class="{'has-error': myForm.notional.$invalid && myForm.notional.$touched}">
                    <input type="text" ng-model="myForm.money.notional  " money="money" money-input size="30" required
                           name="notional"
                           class="form-control"
                           placeholder="Enter notional amount"/>
    
                          <p class="help-block error" ng-show="myForm.notional.$error.required && myForm.notional.$touched">Required</p>
    
    
    
                </div>
    
                <button ng-disabled="myForm.$invalid" type="submit">SAVE</button>
            </form>
            <h2>Tips</h2>
            <ol>
    
                <li> Entering 'k' will multiply the amount by one thousand</li>
                <li> Entering 'm' will multiply the amount by one million</li>
                <li> Entering 'b' will multiply the amount by one billion</li>
            </ol>
        </div>
    </div>
    <p>Form debugger</p>
    <pre>
                   form = {{ myForm | json }}
        </pre>
    

答案 4 :(得分:0)

这是一种只使用Angular指令在没有jQuery的情况下处理这个问题的方法。此示例不支持小数。尽管如此,只需更改$filter函数中的toView()即可轻松修改它以支持它。

在我看来,这是解决同一问题的更好方法,因为您可以避免加载jQuery和作者提到的货币插件。使用$locale属性应支持对欧元的区域设置支持,但我只测试了这个用于美元。

(function() {
  var app = angular.module('currencyMask', []);

  // Controller
  app.controller('ctrl', ['$scope', function($scope) {
    $scope.amount = 100000;
  }]);

  // Directive
  app.directive('inputCurrency', ['$locale', '$filter', function($locale, $filter) {

    // For input validation
    var isValid = function(val) {
      return angular.isNumber(val) && !isNaN(val);
    };

    // Helper for creating RegExp's
    var toRegExp = function(val) {
      var escaped = val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
      return new RegExp(escaped, 'g');
    };

    // Saved to your $scope/model
    var toModel = function(val) {

      // Locale currency support
      var decimal = toRegExp($locale.NUMBER_FORMATS.DECIMAL_SEP);
      var group = toRegExp($locale.NUMBER_FORMATS.GROUP_SEP);
      var currency = toRegExp($locale.NUMBER_FORMATS.CURRENCY_SYM);

      // Strip currency related characters from string
      val = val.replace(decimal, '').replace(group, '').replace(currency, '').trim();

      return parseInt(val, 10);
    };

    // Displayed in the input to users
    var toView = function(val) {
      return $filter('currency')(val, '$', 0);
    };

    // Link to DOM
    var link = function($scope, $element, $attrs, $ngModel) {
      $ngModel.$formatters.push(toView);
      $ngModel.$parsers.push(toModel);
      $ngModel.$validators.currency = isValid;

      $element.on('keyup', function() {
        $ngModel.$viewValue = toView($ngModel.$modelValue);
        $ngModel.$render();
      });
    };

    return {
      restrict: 'A',
      require: 'ngModel',
      link: link
    };
  }]);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>

<div ng-app="currencyMask" ng-controller="ctrl">
	<input input-currency ng-model="amount">
	<p><strong>Amount:</strong> {{ amount }}</p>
</div>