AngularJS - How to apply currency filter on textbox as I type?

£可爱£侵袭症+ 提交于 2019-12-04 10:49:57

It is a rather non-trivial problem. For the main part of the functionality, you need to use ngModelController's $formatters and $parsers properties to register listeners to handle the changes in $modelValue and $viewValue respectively.

  1. When the $modelValue changes, you need to filter it using the currency filter before displaying it to the view.

  2. When the $viewValue changes, you need to convert it to a number (I thought it makes more sense to store the model value as number, not as a formatted string), filter that number through the currency filter and update the $viewValue (if necessary).

That is not particularly difficult. The tricky part is that updating the element's value, moves the cursor at the end, so you need to manually re-position the caret.

My attempt resulted in the following Directive Definition Object

{
  restrict: 'A',
  require: 'ngModel',
  link: function postLink(scope, elem, attrs, modelCtrl) {    
    modelCtrl.$formatters.push(filterFunc);
    modelCtrl.$parsers.push(function (newViewValue) {
      var newModelValue = toNumber(newViewValue);
      modelCtrl.$viewValue = filterFunc(newModelValue);
      var pos = getCaretPosition(elem[0]);
      elem.val(modelCtrl.$viewValue);
      var newPos = pos + modelCtrl.$viewValue.length -
                         newViewValue.length;
      setCaretPosition(elem[0], newPos);
      return newModelValue;
    });
  }
};

See, also, this short demo. It's not perfect, but it's a good start. BTW, I "borrowed" the get/setCaretPosition() functions from AngularUI's uiMask directive.

You can also use the fcsa-number directive that provides this for you automatically. It's as easy as adding the fcsa-number attribute to the input element.

<input type="text" fcsa-number />

And here is a demo

The source code and documentation is available on GitHub: https://github.com/FCSAmericaDev/angular-fcsa-number

I have the same problem when try to build a custom currency directive. So, after check many ways to solve I found the angular-input-masks directives.

Support bower for a quick installation and to use just have to add the ui-money-mask attribute on a input text element:

<input type="text" ng-model="money" ui-money-mask>

Also support min and max values validation.

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